Camera图片特效处理综述(Bitmap的Pixels处理、Canvas/paint的drawBitmap处理、旋转图片、裁截图片、播放幻灯片浏览图片<线程固定时间显示一张>)
一种是直接对Bitmap的像素进行操作,如:叠加、边框、怀旧、(高斯)模糊、锐化(拉普拉斯变换)。
Bitmap.getPixels(srcPixels, 0, width, 0, 0, width, height);
newR = (int) (pixR * alpha + layR * (1 - alpha));
newR = Math.min(255, Math.max(0, newR));
。。。
srcPixels[pos] = Color.argb(newA, newR, newG, newB);
Bitmap.setPixels(srcPixels, 0, width, 0, 0, width, height);
另一种是使用画布Canvas自带的函数进行处理,如:圆角、倒影、色相、饱和度、亮度、涂鸦:
Canvas canvas = new Canvas();//创建 空白画布,或new Canvas(bitmap)创建有背景画布,根据情况选择
Paint paint = new Paint();
。。。
canvas.drawBitmap(bitmap, null, rect, paint);
使用画布Canvas自带的函数进行处理的代码,以圆角特效为例:
- //圆角特效
- public static Bitmap getRoundCornerImage(Bitmap bitmap, int roundPixels, int width, int height )
- {
- //创建一个和原始图片一样大小位图
- Bitmap roundConcerImage = Bitmap.createBitmap(width, height, Config.ARGB_8888);
- //创建带有位图roundConcerImage的画布
- Canvas canvas = new Canvas(roundConcerImage);
- //创建画笔
- Paint paint = new Paint();
- //创建一个和原始图片一样大小的矩形
- Rect rect = new Rect(0, 0, width, height);
- RectF rectF = new RectF(rect);
- // 去锯齿
- paint.setAntiAlias(true);
- //画一个和原始图片一样大小的圆角矩形
- canvas.drawRoundRect(rectF, roundPixels, roundPixels, paint);
- //设置相交模式
- paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
- //把图片画到矩形去
- canvas.drawBitmap(bitmap, null, rect, paint);
- return roundConcerImage;
- }
直接对Bitmap的像素进行处理的代码,以怀旧特效为例:
- Handler handler = new Handler(){
- @Override
- public void handleMessage(Message msg) {
- Drawable targetBitmapDrawable = new BitmapDrawable((Bitmap) msg.obj);// 将Bitmap转换为Drawable
- is.setImageDrawable(targetBitmapDrawable);
- }
- };
- /**
- * 怀旧效果
- * @param bmp
- * @return
- */
- private void oldRemeber(final Bitmap bmp)
- {
- Thread thread = new Thread() {
- @Override
- public void run() {
- int width = bmp.getWidth();
- int height = bmp.getHeight();
- Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
- int pixColor = 0;
- int pixR = 0;
- int pixG = 0;
- int pixB = 0;
- int newR = 0;
- int newG = 0;
- int newB = 0;
- int[] pixels = new int[width * height];
- bmp.getPixels(pixels, 0, width, 0, 0, width, height);
- for (int i = 0; i < height; i++)
- {
- for (int k = 0; k < width; k++)
- {
- pixColor = pixels[width * i + k];
- pixR = Color.red(pixColor);
- pixG = Color.green(pixColor);
- pixB = Color.blue(pixColor);
- newR = (int) (0.393 * pixR + 0.769 * pixG + 0.189 * pixB);
- newG = (int) (0.349 * pixR + 0.686 * pixG + 0.168 * pixB);
- newB = (int) (0.272 * pixR + 0.534 * pixG + 0.131 * pixB);
- int newColor = Color.argb(255, newR > 255 ? 255 : newR, newG > 255 ? 255 : newG, newB > 255 ? 255 : newB);
- pixels[width * i + k] = newColor;
- }
- }
- bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
- Message message = handler.obtainMessage();
- message.obj = bitmap;
- handler.sendMessage(message);
- }
- };
- thread.start();
- thread = null;
- }
涂鸦特效再说明:
canvas = new Canvas(originalBitmap);//以原图片为背景创建画布
canvas.drawLine(startX, startY, clickX, clickY, paint);//根据手指移动画线条
canvas.drawBitmap(finalBitmap, 0, 0,null);//
左右旋转图片再说明:
- File MatrixLeftFile=new File(currentImagePath);
- try
- {
- BitmapOrgLeft = BitmapFactory.decodeStream(new FileInputStream(MatrixLeftFile), null, RotateOptions);
- }
- catch (FileNotFoundException e2)
- {
- // TODO 自动生成的 catch 块
- e2.printStackTrace();
- }
- BitmapOrgLeft = Bitmap.createBitmap(BitmapOrgLeft, 0, 0, BitmapOrgLeft.getWidth(), BitmapOrgLeft.getHeight(), matrixleft, true);
- try
- {
- bos = new BufferedOutputStream(new FileOutputStream(MatrixLeftFile));
- }
- catch (FileNotFoundException e1)
- {
- // TODO 自动生成的 catch 块
- e1.printStackTrace();
- }
- /* 采用压缩转档方法 */
- BitmapOrgLeft.compress(Bitmap.CompressFormat.JPEG, 100, bos);
- /* 调用flush()方法,更新BufferStream */
- try {
- bos.flush();
- } catch (IOException e) {
- // TODO 自动生成的 catch 块
- e.printStackTrace();
- }
- /* 结束OutputStream */
- try {
- bos.close();
- } catch (IOException e) {
- // TODO 自动生成的 catch 块
- e.printStackTrace();
- }
- imageAdapter.notifyDataSetChanged();
- //调用函数刷新图片
- Refresh_Rotating_Pictures();
- Toast.makeText(getBaseContext(), "保存成功!", Toast.LENGTH_LONG).show();
- //及时的释放 Bitmap 对象
- if(BitmapOrgLeft != null && !BitmapOrgLeft.isRecycled())
- {
- BitmapOrgLeft.recycle();
- BitmapOrgLeft = null;
- }
裁截图片再说明:
主要是两个函数和画布canvas的使用:
public void moveChooseArea(int move_x,int move_y){}:整体调整矩形的四条边,有最大最小限制。
private void pressLB(int x,int y)、 pressLT、 pressRB、 pressRT:调整相邻的某(左、上)两条边,有最大最小限制。
canvas.drawRect(ChooseArea, mPaint);
mPaint.setColor(Color.BLUE);
canvas.drawRect(recLT, mPaint);
canvas.drawRect(recLB, mPaint);
canvas.drawRect(recRT, mPaint);
canvas.drawRect(recRB, mPaint);
canvas.drawRect(leftRectL, leftAreaPaint);
canvas.drawRect(leftRectR, leftAreaPaint);
canvas.drawRect(leftRectT, leftAreaPaint);
canvas.drawRect(leftRectB, leftAreaPaint);
- package com.cutPicture;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Matrix;
- import android.graphics.Paint;
- import android.graphics.RectF;
- import android.graphics.Bitmap.Config;
- import android.graphics.drawable.BitmapDrawable;
- import android.util.AttributeSet;
- import android.view.MotionEvent;
- import android.widget.ImageView;
- //http://www.cdtarena.com/gpx/201305/8653.html
- public class MyCutView extends ImageView {
- private final static int PRESS_LB = 0;//表示左下角矩形框
- private final static int PRESS_LT = 1;//表示左上角矩形框
- private final static int PRESS_RB = 2;//表示右下角矩形框
- private final static int PRESS_RT = 3;//表示右上角矩形框
- private Bitmap bitMap = null; //原始图片
- private RectF src = null; //经过比例转换后的裁剪区域
- private RectF dst = null; //图片显示区域,也就是drawBitmap函数中的目标dst
- private RectF ChooseArea = null; //选择区域
- private Paint mPaint = null; //画笔
- private Matrix matrix = null; //矩阵
- private int mx = 0; //存储触笔移动时,之前**的触笔的x坐标
- private int my = 0; //存储触笔移动时,之前**的触笔的y坐标
- private boolean touchFlag = false; //触笔是否在屏幕之*?
- private boolean cutFlag = false; //是否点击了menu上的裁剪按钮
- private int recFlag = -1; //用来存储触笔点击了哪个小矩形框(改变选择区域大小的小矩形框)
- private boolean firstFlag = false;
- private RectF recLT = null; //左上角的小矩形框
- private RectF recRT = null; //右上角的小矩形框
- private RectF recLB = null; //左下角的小矩形框
- private RectF recRB = null; //右下角的小矩形框
- private static final int LEFT_AREA_ALPHA = 50 * 255 / 100;
- private RectF leftRectL = null;
- private RectF leftRectR = null;
- private RectF leftRectT = null;
- private RectF leftRectB = null;
- private Paint leftAreaPaint = null;
- int padding=0;
- public String editImagePath=null;
- public MyCutView(Context context, AttributeSet attrs) {
- super(context, attrs);
- this.init();
- }
- public MyCutView(Context context) {
- super(context);
- this.init();
- }
- public void init(){
- cutFlag = true;
- recLT = new RectF();
- recLB = new RectF();
- recRT = new RectF();
- recRB = new RectF();
- dst = new RectF();
- mPaint = new Paint();
- mPaint.setColor(Color.RED);
- mPaint.setStyle(Paint.Style.STROKE); //将画笔的风格改为空心
- ChooseArea = new RectF();
- this.setPressRecLoc();
- src = null;
- firstFlag = true;
- //选择框之外的灰色区域,分成四个矩形框
- leftAreaPaint = new Paint();
- leftAreaPaint.setStyle(Paint.Style.FILL);
- leftAreaPaint.setAlpha(MyCutView.LEFT_AREA_ALPHA);
- }
- public void setBitmap(Bitmap bitmap){
- BitmapDrawable bd = new BitmapDrawable(bitmap);
- src = new RectF(0,0,bd.getIntrinsicWidth(),bd.getIntrinsicHeight());
- this.bitMap = bitmap.copy(Config.ARGB_8888, true);
- this.setImageBitmap(bitMap);
- leftRectB = new RectF();
- leftRectL = new RectF();
- leftRectR = new RectF();
- leftRectT = new RectF();
- }
- public void imageScale(){
- matrix = this.getImageMatrix();
- matrix.mapRect(dst, src);
- padding = this.getPaddingBottom();
- /*
- int width = bitMap.getWidth();
- int height = bitMap.getHeight();
- //dst.set(dst.left+padding,dst.top+padding,dst.right+padding,dst.bottom+padding);
- if(height>width)
- {
- dst.set(dst.left,dst.top,width-7,height+100); 适用于android:layout_width="wrap_content"是FillParent并且没有android:layout_centerInParent="true"属性
- }
- else
- {
- dst.set(dst.left,dst.top,width-170,height+120);
- }
- */
- int w=this.getWidth();
- int h=this.getHeight();
- //if(h>w)
- {
- dst.set(dst.left+2,dst.top+2,w-4,h-6);
- }
- //else
- if(editImagePath!=null)
- {
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(editImagePath, options);
- int tempH = options.outHeight;
- if(tempH==1944)
- {
- dst.set(dst.left+2,dst.top+2,w-4,h-67);
- }
- }
- ChooseArea = new RectF(dst);
- this.setPressRecLoc();
- }
- public Bitmap getSubsetBitmap(){
- float ratioWidth = bitMap.getWidth()/(float)(dst.right-dst.left);
- float ratioHeight = bitMap.getHeight()/(float)(dst.bottom - dst.top);
- int left = (int)((ChooseArea.left - dst.left) * ratioWidth);
- int right = (int)(left + (ChooseArea.right - ChooseArea.left) * ratioWidth);
- int top = (int)((ChooseArea.top - dst.top) * ratioHeight);
- int bottom = (int)(top + (ChooseArea.bottom - ChooseArea.top) * ratioHeight);
- src = new RectF(left,top,right,bottom);
- firstFlag = true;
- set_LeftArea_Alpha();
- return Bitmap.createBitmap(bitMap, left, top, right-left, bottom-top);
- }
- //获得ChooseArea对象
- public RectF getChooseArea(){
- return ChooseArea;
- }
- public void moveChooseArea(int move_x,int move_y){
- if(ChooseArea.left + move_x >= dst.left && ChooseArea.right + move_x <= dst.right
- && ChooseArea.top + move_y >= dst.top && ChooseArea.bottom + move_y <= dst.bottom){
- ChooseArea.set(ChooseArea.left + move_x,ChooseArea.top+move_y
- ,ChooseArea.right + move_x,ChooseArea.bottom+move_y);
- }else{
- if(ChooseArea.left + move_x < dst.left){
- ChooseArea.set(dst.left,ChooseArea.top
- ,ChooseArea.right+dst.left-ChooseArea.left,ChooseArea.bottom);
- }
- if(ChooseArea.right + move_x > dst.right){
- ChooseArea.set(ChooseArea.left+dst.right-ChooseArea.right,ChooseArea.top
- ,dst.right,ChooseArea.bottom);
- }
- if(ChooseArea.top + move_y < dst.top){
- ChooseArea.set(ChooseArea.left,dst.top
- ,ChooseArea.right,ChooseArea.bottom+dst.top-ChooseArea.top);
- }
- if(ChooseArea.bottom + move_y > dst.bottom){
- ChooseArea.set(ChooseArea.left,ChooseArea.top+dst.bottom-ChooseArea.bottom
- ,ChooseArea.right,dst.bottom);
- }
- }
- this.setPressRecLoc();
- mPaint.setColor(Color.GREEN);
- this.invalidate();
- }
- public boolean onTouchEvent(MotionEvent event){
- mPaint.setColor(Color.RED);
- if(event.getAction() == MotionEvent.ACTION_DOWN && cutFlag){
- //System.out.println(event.getX() + "," + event.getY());
- mx = (int)event.getX();
- my = (int)event.getY();
- if(this.judgeLocation(mx,my)){
- touchFlag = true;
- mPaint.setColor(Color.GREEN);
- this.invalidate();
- return true;
- }else{
- if(this.findPresseddst((int)event.getX(), (int)event.getY())){
- touchFlag = true;
- mPaint.setColor(Color.RED);
- return true;
- }
- }
- }
- if(event.getAction() == MotionEvent.ACTION_MOVE && touchFlag){
- //判断是否点击了哪个个小矩形框
- if(this.isOutOfArea((int)event.getX(), (int)event.getY())){
- return true;
- }
- //www.cdtarena.com如果选择区域大小跟图像大小一样时,就不能移动
- if(ChooseArea.left == dst.left && ChooseArea.top == dst.top &&
- ChooseArea.right == dst.right && ChooseArea.bottom == dst.bottom){
- }else{
- this.moveChooseArea((int)event.getX() - mx, (int)event.getY() - my);
- mx = (int)event.getX();
- my = (int)event.getY();
- }
- }
- if(event.getAction() == MotionEvent.ACTION_UP){
- recFlag = -1;
- this.invalidate();
- touchFlag = false;
- }
- return super.onTouchEvent(event);
- }
- private boolean isOutOfArea(int x,int y){
- switch(recFlag){
- case MyCutView.PRESS_LB:
- this.pressLB(x - mx, y - my);
- break;
- case MyCutView.PRESS_LT:
- this.pressLT(x - mx, y - my);
- break;
- case MyCutView.PRESS_RB:
- this.pressRB(x - mx, y - my);
- break;
- case MyCutView.PRESS_RT:
- this.pressRT(x - mx, y - my);
- break;
- default:return false;
- }
- mx = x;
- my = y;
- this.invalidate();
- return true;
- }
- public boolean findPresseddst(int x,int y){
- boolean returnFlag = false;
- if(this.isInRect(x, y, recLB)){
- recFlag = MyCutView.PRESS_LB;
- returnFlag = true;
- }else if(this.isInRect(x, y, recLT)){
- recFlag = MyCutView.PRESS_LT;
- returnFlag = true;
- }else if(this.isInRect(x, y, recRB)){
- recFlag = MyCutView.PRESS_RB;
- returnFlag = true;
- }else if(this.isInRect(x, y, recRT)){
- recFlag = MyCutView.PRESS_RT;
- returnFlag = true;
- }
- return returnFlag;
- }
- public boolean isInRect(int x,int y,RectF rect){
- if(x >= rect.left -20 && x <= rect.right + 20 && y > rect.top - 20 && y < rect.bottom + 20){
- return true;
- }
- return false;
- }
- private void pressLB(int x,int y){
- float left = ChooseArea.left + x;
- float right = ChooseArea.right;
- float top = ChooseArea.top;
- float bottom = ChooseArea.bottom + y;
- if(left <= right - 30 && left >= dst.left && bottom <= dst.bottom && bottom >= top + 30){
- ChooseArea.set(left,top,right,bottom);
- }else{
- if(left + x < dst.left){
- left = dst.left;
- }
- if(bottom + y > dst.bottom){
- bottom = dst.bottom;
- }
- if(ChooseArea.left + x > ChooseArea.right - 30){
- left = ChooseArea.right - 30;
- }
- if(ChooseArea.bottom + y < ChooseArea.top + 30){
- bottom = ChooseArea.top + 30;
- }
- ChooseArea.set(left,top,right,bottom);
- }
- this.setPressRecLoc();
- }
- private void pressLT(int x,int y){
- float left = ChooseArea.left + x;
- float right = ChooseArea.right;
- float top = ChooseArea.top + y;
- float bottom = ChooseArea.bottom;
- if(left <= right - 30 && left >= dst.left && top <= bottom - 30 && top >= dst.top){
- ChooseArea.set(left,top,right,bottom);
- }else{
- if(left < dst.left){
- left = dst.left;
- }
- if(top < dst.top){
- top = dst.top;
- }
- if(left > right - 30){
- left = right - 30;
- }
- if(top > bottom - 30){
- top = bottom - 30;
- }
- ChooseArea.set(left,top,right,bottom);
- }
- this.setPressRecLoc();
- }
- private void pressRT(int x,int y){
- float left = ChooseArea.left;
- float right = ChooseArea.right + x;
- float top = ChooseArea.top + y;
- float bottom = ChooseArea.bottom;
- if(right <= dst.right && right >= left + 30 && top <= bottom - 30 && top >= dst.top){
- ChooseArea.set(left,top,right,bottom);
- }else{
- if(right > dst.right){
- right = dst.right;
- }
- if(top < dst.top){
- top = dst.top;
- }
- if(right < left + 30){
- right = left + 30;
- }
- if(top > bottom - 30){
- top = bottom - 30;
- }
- ChooseArea.set(left,top,right,bottom);
- }
- this.setPressRecLoc();
- }
- private void pressRB(int x,int y){
- float left = ChooseArea.left;
- float right = ChooseArea.right + x;
- float top = ChooseArea.top;
- float bottom = ChooseArea.bottom + y;
- if(right<= dst.right && right >= left + 30 && bottom <= dst.bottom && bottom >= top + 30){
- ChooseArea.set(left,top,right,bottom);
- }else{
- if(right > dst.right){
- right = dst.right;
- }
- if(bottom > dst.bottom){
- bottom = dst.bottom;
- }
- if(right < left + 30){
- right = left + 30;
- }
- if(bottom < top + 30){
- bottom = top + 30;
- }
- ChooseArea.set(left,top,right,bottom);
- }
- this.setPressRecLoc();
- }
- //每次改变选择区域矩形的大小或者移动,各角落上的小矩形也要改变它的Location
- private void setPressRecLoc(){
- recLT.set(ChooseArea.left-5,ChooseArea.top-5 , ChooseArea.left+5, ChooseArea.top+5);
- recLB.set(ChooseArea.left-5,ChooseArea.bottom-5 , ChooseArea.left+5, ChooseArea.bottom+5);
- recRT.set(ChooseArea.right-5,ChooseArea.top-5 , ChooseArea.right+5, ChooseArea.top+5);
- recRB.set(ChooseArea.right-5,ChooseArea.bottom-5 , ChooseArea.right+5, ChooseArea.bottom+5);
- }
- public boolean judgeLocation(float x,float y){
- float start_x = this.getChooseArea().left;
- float start_y = this.getChooseArea().top;
- float last_x = this.getChooseArea().right;
- float last_y = this.getChooseArea().bottom;
- //System.out.println("chubi:" + x + "," + y);
- //System.out.println(start_y + "," + last_y);
- if(x > start_x+10 && x < last_x-10 && y > start_y+10 && y < last_y-10){
- return true;
- }
- return false;
- }
- public void onDraw(Canvas canvas){
- super.onDraw(canvas);
- if(firstFlag){
- this.imageScale();
- firstFlag = false;
- mPaint.setColor(Color.RED);
- System.out.println("Width: " + (dst.right - dst.left));
- System.out.println("Height: " + (dst.bottom - dst.top));
- System.out.println("Width: " + this.getDrawable().getIntrinsicWidth());
- System.out.println("Height: " + this.getDrawable().getIntrinsicHeight());
- }else{
- set_LeftArea_Alpha();
- }
- canvas.drawRect(ChooseArea, mPaint);
- mPaint.setColor(Color.BLUE);
- canvas.drawRect(recLT, mPaint);
- canvas.drawRect(recLB, mPaint);
- canvas.drawRect(recRT, mPaint);
- canvas.drawRect(recRB, mPaint);
- canvas.drawRect(leftRectL, leftAreaPaint);
- canvas.drawRect(leftRectR, leftAreaPaint);
- canvas.drawRect(leftRectT, leftAreaPaint);
- canvas.drawRect(leftRectB, leftAreaPaint);
- }
- public void set_LeftArea_Alpha(){
- leftRectL.set(dst.left, dst.top, ChooseArea.left, dst.bottom);
- leftRectR.set(ChooseArea.right,dst.top,dst.right,dst.bottom);
- leftRectT.set(ChooseArea.left, dst.top, ChooseArea.right, ChooseArea.top);
- leftRectB.set(ChooseArea.left,ChooseArea.bottom,ChooseArea.right,dst.bottom);
- }
- }
播放幻灯片浏览图片再说明:
使用两个全局变量:
public String[] myImageNames; //所有的图片的名字
public int ImageNameId = 0; //图片编号
public String picfolderPath; //实际上是 文件夹 的路径
开个线程,每3秒显示一张图片:
ImagePath = picfolderPath + File.separator + myImageNames[ImageNameId];
ImageNameId++;
- public String picfolderPath; //实际上是 文件夹 的路径
- public String[] myImageNames; //所有的图片的名字
- public int ImageNameId = 0; //图片编号
- public String ImagePath ; //图片的路径
- is = (ImageSwitcher) findViewById(R.id.slideshow_switcher);
- is.setFactory(this);
- is.setInAnimation(AnimationUtils.loadAnimation(this,android.R.anim.fade_in));
- is.setOutAnimation(AnimationUtils.loadAnimation(this,android.R.anim.fade_out));
- Runnable runnable=new Runnable() { //采用Handler的postDelayed(Runnable, long)方法 计时
- @Override
- public void run() {
- // TODO Auto-generated method stub
- if(ImageNameId < myImageNames.length)
- {
- is.reset();
- ImagePath = picfolderPath + File.separator + myImageNames[ImageNameId];
- ImageNameId++;
- getSampledBitmap(ImagePath);
- }
- else if(ImageNameId ==myImageNames.length)
- {
- is.reset();
- ImageNameId = 0; //重置 ImageNameId,实现循环播放
- ImagePath = picfolderPath + File.separator + myImageNames[ImageNameId];
- ImageNameId++;
- getSampledBitmap(ImagePath);
- }
- //handler.removeCallbacks(runnable);//停止计时器
- //handler.postDelayed(this, 3000);//3秒时间间隔
- }
- };
Camera图片特效处理综述(Bitmap的Pixels处理、Canvas/paint的drawBitmap处理、旋转图片、裁截图片、播放幻灯片浏览图片<线程固定时间显示一张>)的更多相关文章
- android图片特效处理之模糊效果
这篇将讲到图片特效处理的模糊效果.跟前面一样是对像素点进行处理,算法是通用的,但耗时会更长,至于为什么,看了下面的代码你就会明白. 算法: 一.简单算法:将像素点周围八个点包括自身一共九个点的RGB值 ...
- android 图片特效处理之 光晕效果
这篇将讲到图片特效处理的图片光晕效果.跟前面一样是对像素点进行处理,本篇实现的思路可参见android图像处理系列之九--图片特效处理之二-模糊效果和android图像处理系列之十三--图片特效处理之 ...
- android 图片特效处理之光晕效果
这篇将讲到图片特效处理的图片光晕效果.跟前面一样是对像素点进行处理,本篇实现的思路可参见android图像处理系列之九--图片特效处理之二-模糊效果和android图像处理系列之十三--图片特效处理之 ...
- android 图片特效处理之锐化效果
这篇将讲到图片特效处理的锐化效果.跟前面一样是对像素点进行处理,算法是通用的. 算法原理: 一.简单算法:分别获取当前像素点和八个周围像素点的RGB值,先求出当前像素点的RGB值与八个像素点RGB值的 ...
- android 图片特效处理之模糊效果
这篇将讲到图片特效处理的模糊效果.跟前面一样是对像素点进行处理,算法是通用的,但耗时会更长,至于为什么,看了下面的代码你就会明白. 算法: 一.简单算法:将像素点周围八个点包括自身一共九个点的RGB值 ...
- android 图片特效处理之怀旧效果
图片特效处理系列将介绍图片的像素点的特效处理,这些物资注重的是原理.也就是说只要你知道这些算法不管是C++,VB,C#,Java都可以做出相同的特效.下面将介绍图片怀旧效果的算法.算法如下: 上面公式 ...
- android图片特效处理之怀旧效果
图片特效处理系列将介绍图片的像素点的特效处理,这些物资注重的是原理.也就是说只要你知道这些算法不管是C++,VB,C#,Java都可以做出相同的特效.下面将介绍图片怀旧效果的算法.算法如下: 上面公式 ...
- android图片特效处理之锐化效果
这篇将讲到图片特效处理的锐化效果.跟前面一样是对像素点进行处理,算法是通用的. 算法原理: 一.简单算法:分别获取当前像素点和八个周围像素点的RGB值,先求出当前像素点的RGB值与八个像素点RGB值的 ...
- android图片特效处理之光晕效果
这篇将讲到图片特效处理的图片光晕效果.跟前面一样是对像素点进行处理,本篇实现的思路可参见android图像处理系列之九--图片特效处理之二-模糊效果和android图像处理系列之十三--图片特效处理之 ...
随机推荐
- VC程序查错之内存访问异常
作者:langouster 先来看下面这张图,相信很多程序员都见过类似. ---------------------------test1.exe - 应用程序错误------------------ ...
- JavaScript DOM编程基础精华03(动态设置,层的操作,性能问题)
代码是否需要放置到onload中 //如果js代码需要操作页面上的元素,则将该代码放到onload里面. //因为当页面加载完毕之后页面上才会有相关的元素 //如果js代码中没有操作 ...
- ORA-12571 : TNS : 包写入程序失败
错误原因 解决方案 修改D:/oracle/ora92/network/admin目录下sqlnet.ora,将”NAMES.DEFAULT_DOMAIN =” 这一行用#注释掉,将“SQLNET.A ...
- C++:运算符重载函数
5.运算符重载 5.1 在类外定义的运算符重载函数 C++为运算符重载提供了一种方法,即在运行运算符重载时,必须定义一个运算符重载函数,其名字为operator,后随一个要重载的运算符.例如,要重载& ...
- Splunk作为日志分析平台与Ossec进行联动
背景: Ossec安装后用了一段时间的analogi作为ossec的报警信息显示平台,但是查看报警分类信息. 以及相关图标展示等方面总有那么一点点的差强人意,难以分析.因此使用逼格高一点的splunk ...
- 4、JPA table主键生成策略(在JPA中table策略是首推!!!)
用 table 来生成主键详解 它是在不影响性能情况下,通用性最强的 JPA 主键生成器.这种方法生成主键的策略可以适用于任何数据库,不必担心不同数据库不兼容造成的问题. initialValue不起 ...
- (四)CSS选择器和派生选择器
CSS派生选择器允许你根据文档的上下文关系来确定某个标签的样式.在学习派生之前,先来了解基本的CSS选择器.前面的文章中提到过下图,选择器的位置如下所示: CSS选择器 分为几种基本选择器:元素选择器 ...
- java导出excel报表
1.java导出excel报表: package cn.jcenterhome.util; import java.io.OutputStream;import java.util.List;impo ...
- Bug:java.lang.IllegalStateException
使用迭代的时候,出现了java.lang.IllegalStateException 代码: for ( TaskInfo info : userTaskInfos ) { if ( info.isC ...
- Oracle学习之集合运算
一.集合运算操作符 UNION:(并集)返回两个集合去掉重复值的所有的记录 UNION ALL:(并集)返回两个集合去掉重复值的所有的记录 INTERSECT:(交集)返回两个集合的所有记录,重复 ...