文档章节

android 图像处理(黑白,模糊,浮雕,圆角,镜像,底片,油画,灰白,加旧)

yolinfeng
 yolinfeng
发布于 2015/04/29 14:34
字数 1891
阅读 39
收藏 0

圆角处理

public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, float roundPx) {
  Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
    bitmap.getHeight(), Config.ARGB_8888);
  Canvas canvas = new Canvas(output);
  final int color = 0xff424242;
  final Paint paint = new Paint();
  final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
  final RectF rectF = new RectF(rect);
  paint.setAntiAlias(true);
  canvas.drawARGB(0, 0, 0, 0);
  paint.setColor(color);
  canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
  paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
  canvas.drawBitmap(bitmap, rect, rect, paint);
  return output;
 }

这个就简单了,实际上是在原图片上画了一个圆角遮罩。对于paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));方法我刚看到也是一知半解Mode.SRC_IN参数是个画图模式,该类型是指只显示两层图案的交集部分,且交集部位只显示上层图像。实际就是先画了一个圆角矩形的过滤框,于是形状有了,再将框中的内容填充为图片。该参数总过有十八种。

 

灰白处理

public static Bitmap toGrayscale(Bitmap bmpOriginal) {
  int width, height;
  height = bmpOriginal.getHeight();
  width = bmpOriginal.getWidth();
  Bitmap bmpGrayscale = Bitmap.createBitmap(width, height,
    Bitmap.Config.RGB_565);
  Canvas c = new Canvas(bmpGrayscale);
  Paint paint = new Paint();
  ColorMatrix cm = new ColorMatrix();
  cm.setSaturation(0);
  ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
  paint.setColorFilter(f);
  c.drawBitmap(bmpOriginal, 0, 0, paint);
  return bmpGrayscale;
 }

 这个也没什么好说的,就是利用了ColorMatrix 类自带的设置饱和度的方法setSaturation()。不过其方法内部实现的更深一层是利用颜色矩阵的乘法实现的,对于颜色矩阵的乘法下面还有使用。

 

黑白处理

public static Bitmap toHeibai(Bitmap mBitmap) {
  int mBitmapWidth = 0;
  int mBitmapHeight = 0;
  mBitmapWidth = mBitmap.getWidth();
  mBitmapHeight = mBitmap.getHeight();
  Bitmap bmpReturn = Bitmap.createBitmap(mBitmapWidth, mBitmapHeight,
    Bitmap.Config.ARGB_8888);
  int iPixel = 0;
  for (int i = 0; i < mBitmapWidth; i++) {
   for (int j = 0; j < mBitmapHeight; j++) {
    int curr_color = mBitmap.getPixel(i, j);
    int avg = (Color.red(curr_color) + Color.green(curr_color) + Color
      .blue(curr_color)) / 3;
    if (avg >= 100) {
     iPixel = 255;
    } else {
     iPixel = 0;
    }
    int modif_color = Color.argb(255, iPixel, iPixel, iPixel);
    bmpReturn.setPixel(i, j, modif_color);
   }
  }
  return bmpReturn;
 }

其实看图片效果就能看出来,这张图片不同于灰白处理的那张,不同之处是灰白处理虽然没有了颜色,但是黑白的程度层次依然存在,而此张图片连层次都没有了,只有两个区别十分明显的黑白颜色。实现的算法也很简单,对于每个像素的rgb值求平均数,如果高于100算白色,低于100算黑色。不过感觉100这个标准值太大了,导致图片白色区域太多,把它降低点可能效果会更好。

 

镜像处理

 public static Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {
  final int reflectionGap = 4;
  int width = bitmap.getWidth();
  int height = bitmap.getHeight();
  Matrix matrix = new Matrix();
  matrix.preScale(1, -1);
  Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height / 2,
    width, height / 2, matrix, false);
  Bitmap bitmapWithReflection = Bitmap.createBitmap(width,
    (height + height / 2), Config.ARGB_8888);
  Canvas canvas = new Canvas(bitmapWithReflection);
  canvas.drawBitmap(bitmap, 0, 0, null);
  Paint deafalutPaint = new Paint();
  canvas.drawRect(0, height, width, height + reflectionGap, deafalutPaint);
  canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
  Paint paint = new Paint();
  LinearGradient shader = new LinearGradient(0, bitmap.getHeight(), 0,
    bitmapWithReflection.getHeight() + reflectionGap, 0x70ffffff,
    0x00ffffff, TileMode.CLAMP);
  paint.setShader(shader);
  // Set the Transfer mode to be porter duff and destination in
  paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
  // Draw a rectangle using the paint with our linear gradient
  canvas.drawRect(0, height, width, bitmapWithReflection.getHeight()
    + reflectionGap, paint);
  return bitmapWithReflection;
 }

记得去年android入门时做过gallery的倒影特效,当时感觉很漂亮,想着需要作出反转和倾斜就可以了,原来他也是这么做的。原理就是将原图片反转一下,调整一 下它的颜色作出倒影效果,再将两张图片续加在一起,不过如果在反转的同时再利用Matrix加上一些倾斜角度就更好了,不过那样做的话加工后的图片的高度需要同比例计算出来,不能简单的相加了,否则就图片大小就容不下现有的像素内容。

 

加旧处理

public static Bitmap testBitmap(Bitmap bitmap) {
  Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
    bitmap.getHeight(), Config.RGB_565);
  Canvas canvas = new Canvas(output);
  Paint paint = new Paint();
  ColorMatrix cm = new ColorMatrix();
  float[] array = { 1, 0, 0, 0, 50, 0, 1, 0, 0, 50, 0, 0, 1, 0, 0, 0, 0,
    0, 1, 0 };
  cm.set(array);
  paint.setColorFilter(new ColorMatrixColorFilter(cm));
  canvas.drawBitmap(bitmap, 0, 0, paint);
  return output;
 }

 其实每张图片的存储都是存的每个像素的rgba值,而对其操作的时候又将其四个数值定位一个5行1列的矩阵,最后一行值为1,这样一来利用矩阵对其操作确实方便了好多,矩阵的乘法可以轻松的实现某个或全部分量按比例或加常熟的增加或减少。 比如现有一张图片,其每个point的rgba值为{100,100,100,255}也就是灰色全图,我们希望其红色部位增加一倍,剩余部分增加十。就可以将其值虚拟为五行一列矩阵:{100 ,100,100,255,1} 再让这个矩阵:{2,0,0,0,0换行 0,1,0,0,10换行 0,0,1,0,10换行 0,,0,0,1,10} 乘以它。得到{ 200,110,100,100} 。 这个泛黄照片的处理算法原理就是让每个像素点rg值增加50,rg值相混合就得到了黄色。

 

浮雕处理

 public static Bitmap toFuDiao(Bitmap mBitmap) {
  int mBitmapWidth = 0;
  int mBitmapHeight = 0;
  mBitmapWidth = mBitmap.getWidth();
  mBitmapHeight = mBitmap.getHeight();
  Bitmap bmpReturn = Bitmap.createBitmap(mBitmapWidth, mBitmapHeight,
    Bitmap.Config.RGB_565);
  int preColor = 0;
  int prepreColor = 0;
  preColor = mBitmap.getPixel(0, 0);
  for (int i = 0; i < mBitmapWidth; i++) {
   for (int j = 0; j < mBitmapHeight; j++) {
    int curr_color = mBitmap.getPixel(i, j);
    int r = Color.red(curr_color) - Color.red(prepreColor) + 127;
    int g = Color.green(curr_color) - Color.red(prepreColor) + 127;
    int b = Color.green(curr_color) - Color.blue(prepreColor) + 127;
    int a = Color.alpha(curr_color);
    int modif_color = Color.argb(a, r, g, b);
    bmpReturn.setPixel(i, j, modif_color);
    prepreColor = preColor;
    preColor = curr_color;
   }
  }
  Canvas c = new Canvas(bmpReturn);
  Paint paint = new Paint();
  ColorMatrix cm = new ColorMatrix();
  cm.setSaturation(0);
  ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
  paint.setColorFilter(f);
  c.drawBitmap(bmpReturn, 0, 0, paint);
  return bmpReturn;
 }

观察浮雕就不难发现,其实浮雕的特点就是在颜色有跳变的地方就刻条痕迹。127,127,127为深灰色,近似于石头的颜色,此处取该颜色为底色。算法是将上一个点的rgba值减去当前点的rgba值然后加上127得到当前点的颜色。

 

油画处理

 public static Bitmap toYouHua(Bitmap bmpSource) {
  Bitmap bmpReturn = Bitmap.createBitmap(bmpSource.getWidth(),
    bmpSource.getHeight(), Bitmap.Config.RGB_565);
  int color = 0;
  int Radio = 0;
  int width = bmpSource.getWidth();
  int height = bmpSource.getHeight();
  Random rnd = new Random();
  int iModel = 10;
  int i = width - iModel;
  while (i > 1) {
   int j = height - iModel;
   while (j > 1) {
    int iPos = rnd.nextInt(100000) % iModel;
    color = bmpSource.getPixel(i + iPos, j + iPos);
    bmpReturn.setPixel(i, j, color);
    j = j - 1;
   }
   i = i - 1;
  }
  return bmpReturn;
 }

赞一下这个算法,其实应该说鄙视下自己,在看到效果图的时候,我会先猜一下原理,但是这个始终没有想出来。其实油画因为是用画笔画的,彩笔画的时候没有那么精确会将本该这点的颜色滑到另一个点处。算法实现就是取一个一定范围内的随机数,每个点的颜色是该点减去随机数坐标后所得坐标的颜色。

 

模糊处理

public static Bitmap toMohu(Bitmap bmpSource, int Blur) {
  int mode = 5;
  Bitmap bmpReturn = Bitmap.createBitmap(bmpSource.getWidth(),
    bmpSource.getHeight(), Bitmap.Config.ARGB_8888);
  int pixels[] = new int[bmpSource.getWidth() * bmpSource.getHeight()];
  int pixelsRawSource[] = new int[bmpSource.getWidth()
    * bmpSource.getHeight() * 3];
  int pixelsRawNew[] = new int[bmpSource.getWidth()
    * bmpSource.getHeight() * 3];
  bmpSource.getPixels(pixels, 0, bmpSource.getWidth(), 0, 0,
    bmpSource.getWidth(), bmpSource.getHeight());
  for (int k = 1; k <= Blur; k++) {
   for (int i = 0; i < pixels.length; i++) {
    pixelsRawSource[i * 3 + 0] = Color.red(pixels[i]);
    pixelsRawSource[i * 3 + 1] = Color.green(pixels[i]);
    pixelsRawSource[i * 3 + 2] = Color.blue(pixels[i]);
   }
   int CurrentPixel = bmpSource.getWidth() * 3 + 3;
   for (int i = 0; i < bmpSource.getHeight() - 3; i++) {
    for (int j = 0; j < bmpSource.getWidth() * 3; j++) {
     CurrentPixel += 1;
     int sumColor = 0;
     sumColor = pixelsRawSource[CurrentPixel
       - bmpSource.getWidth() * 3];
     sumColor = sumColor + pixelsRawSource[CurrentPixel - 3];
     sumColor = sumColor + pixelsRawSource[CurrentPixel + 3];
     sumColor = sumColor
       + pixelsRawSource[CurrentPixel
         + bmpSource.getWidth() * 3];
     pixelsRawNew[CurrentPixel] = Math.round(sumColor / 4);
    }
   }
   for (int i = 0; i < pixels.length; i++) {
    pixels[i] = Color.rgb(pixelsRawNew[i * 3 + 0],
      pixelsRawNew[i * 3 + 1], pixelsRawNew[i * 3 + 2]);
   }
  }
  bmpReturn.setPixels(pixels, 0, bmpSource.getWidth(), 0, 0,
    bmpSource.getWidth(), bmpSource.getHeight());
  return bmpReturn;
 }

算法实现其实是取每三点的平均值做为当前点颜色,这样看上去就变得模糊了。这个算法是三点的平均值,如果能够将范围扩大,并且不是单纯的平均值,而是加权平均肯定效果会更好。不过处理速度实在是太慢了,而Muzei这种软件在处理的时候,不仅仅速度特别快,而且还有逐渐变模糊的变化过程,显然人家不是用这种算法实现的。他们的实现方法正在猜测中,实现后也来更新。

本文转载自:http://www.2cto.com/kf/201405/298653.html

yolinfeng
粉丝 12
博文 196
码字总数 11946
作品 0
珠海
架构师
私信 提问
Android实战经验之图像处理及特效处理的集锦(总结版)

1 Android学习笔记进阶之在图片上涂鸦(能清屏) 2 Android学习笔记之详细讲解画圆角图片 3 Android学习笔记进阶20之得到图片的缩略图 4 Android学习笔记进阶19之给图片加边框 5 Android学习笔...

xiaosi
2012/03/12
40.2K
25
数字图像处理、拼接,图像静态滤镜(GPUImage/GPU加速) - Android

图像滤镜处理的两种方式:RGB点乘运算;GPU的矩阵运算(效率更高)。图片处理中的计算:RGBA~利用自带的方法修改色调,饱和度,亮度来修改图片;矩阵~利用矩阵计算得到新的矩阵修改图片。 几个...

元谷
03/12
105
0
Qt Quick 图像处理实例之美图秀秀(附源码下载)

在《Qt Quick 之 QML 与 C++ 混合编程详解》一文中我们讲解了 QML 与 C++ 混合编程的方方面面的内容,这次我们通过一个图像处理应用,再来看一下 QML 与 C++ 混合编程的威力,同时也为诸君揭...

foruok
2014/07/16
0
0
实时图像处理和机器学习库 - cv4j

The target is to set up a high quality and real-time image process and machine learning library which is implemented in pure java. The framework can run application on java desk......

匿名
2017/06/13
1K
0
Android图像处理(二)--Paint,Canvas,ColorMatrix详细

android开发中可能经常会用到这些东西; 一.介绍 Paint:画笔 Canvas:画布 Matrix:变换矩阵 Paint 根据我们要画的类型,我们可以选择不同的笔,比如大气磅礴的山水画,我们可以选择大头的毛笔;...

andy521zhu
2015/04/13
241
0

没有更多内容

加载失败,请刷新页面

加载更多

家庭作业——苗钰婷

2 编写一个程序,发出一声警报,然后打印下面的文本: Startled by the sudden sound, Sally shouted, "By the Great Pumpkin, what was that! #include<stdio.h>int main(){......

OSC_Okruuv
17分钟前
4
0
经典系统设计面试题解析:如何设计TinyURL(一)

原文链接: https://www.educative.io/courses/grokking-the-system-design-interview/m2ygV4E81AR 编者注:本文以一道经典的系统设计面试题:《如何设计TinyURL》的参考答案和解析为例,帮助...

APEMESH
18分钟前
2
0
2.面向对象设计原则(7条)

开闭原则 开闭原则的含义是:当应用的需求改变时,在不修改软件实体的源代码或者二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。 实现方法 可以通过“抽象约束、封装变化”来实...

Eappo_Geng
20分钟前
4
0
8086汇编基础 debug P命令 一步完成loop循环

    IDE : Masm for Windows 集成实验环境 2015     OS : Windows 10 x64 typesetting : Markdown    blog : my.oschina.net/zhichengjiu    gitee : gitee.com/zhichengjiu   ......

志成就
24分钟前
3
0
使用nodeJS实现前端项目自动化之项目构建和文件合并

本文转载于:专业的前端网站➜使用nodeJS实现前端项目自动化之项目构建和文件合并 前面的话   一般地,我们使用构建工具来完成项目的自动化操作。本文主要介绍如何使用nodeJS来实现简单的项...

前端老手
38分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部