Android中对图片处理应用比较常见,所以整理了一些对图片的基本操作处理功能方法:
/** * 图片反转 * @param img * @return */ public Bitmap toturn(Bitmap img){ Matrix matrix = new Matrix(); matrix.postRotate(90); /*翻转90度*/ int width = bitmap.getWidth(); int height =bitmap.getHeight(); img = Bitmap.createBitmap(img, 0, 0, width, height, matrix, true); return img; } /** * 图片缩放 * @param bigimage * @param newWidth * @param newHeight * @return */ public Bitmap tochange(Bitmap bigimage,int newWidth,int newHeight){ // 获取这个图片的宽和高 int width = bigimage.getWidth(); int height = bigimage.getHeight(); // 创建操作图片用的matrix对象 Matrix matrix = new Matrix(); // 计算缩放率,新尺寸除原始尺寸 float scaleWidth = ((float) newWidth)/width; float scaleHeight = ((float) newHeight)/height; // 缩放图片动作 matrix.postScale(scaleWidth, scaleHeight); Bitmap bitmap = Bitmap.createBitmap(bigimage, 0, 0, width, height,matrix, true); return bitmap; } /** * 程序切割图片 * @param bitmap * @param x * @param y * @param w * @param h * @return */ public Bitmap BitmapClipBitmap(Bitmap bitmap,int x, int y, int w, int h) { return Bitmap.createBitmap(bitmap, x, y, w, h); } /** * 图片叠加 * @param b * @return */ public Bitmap diejia(Bitmap b){ if(!b.isMutable()){ //设置图片为背景为透明 b = b.copy(Bitmap.Config.RGB_565, true);// } Canvas canvas = new Canvas(b); Bitmap lock=BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); //叠加新图b2 //注意此时绘制坐标是相对于图片b canvas.drawBitmap(lock, 0, 0, null); canvas.save(Canvas.ALL_SAVE_FLAG); canvas.restore(); lock.recycle(); lock=null; return b; } //图片居中叠加: Bitmap centerToFit(Bitmap bitmap, int width, int height, Context context) { final int bitmapWidth = bitmap.getWidth(); final int bitmapHeight = bitmap.getHeight(); if (bitmapWidth < width || bitmapHeight < height) { int color = context.getResources().getColor(R.color.window_background); Bitmap centered = Bitmap.createBitmap(bitmapWidth < width ? width : bitmapWidth, bitmapHeight < height ? height : bitmapHeight, Bitmap.Config.RGB_565); centered.setDensity(bitmap.getDensity()); Canvas canvas = new Canvas(centered); canvas.drawColor(color); canvas.drawBitmap(bitmap, (width - bitmapWidth) / 2.0f, (height - bitmapHeight) / 2.0f, null); bitmap = centered; } return bitmap; }
/** * create the bitmap from a byte array *生成水印图片 * @param src the bitmap object you want proecss * @param watermark the water mark above the src * @return return a bitmap object ,if paramter's length is 0,return null */ private Bitmap createBitmap( Bitmap src, Bitmap watermark ) { String tag = "createBitmap"; Log.d( tag, "create a new bitmap" ); if( src == null ) { return null; } int w = src.getWidth(); int h = src.getHeight(); int ww = watermark.getWidth(); int wh = watermark.getHeight(); //create the new blank bitmap Bitmap newb = Bitmap.createBitmap( w, h, Config.ARGB_8888 );//创建一个新的和SRC长度宽度一样的位图 Canvas cv = new Canvas( newb ); //draw src into cv.drawBitmap( src, 0, 0, null );//在 0,0坐标开始画入src //draw watermark into cv.drawBitmap( watermark, w - ww + 5, h - wh + 5, null );//在src的右下角画入水印 //save all clip cv.save( Canvas.ALL_SAVE_FLAG );//保存 //store cv.restore();//存储 return newb; } //水印图片2: public static Bitmap createWaterMakerBitmap(Bitmap bitmap, Bitmap watermaker){ return createWaterMakerBitmap(bitmap, watermaker, null); } public static Bitmap createWaterMakerBitmap(Bitmap bitmap, Bitmap watermaker, String title){ Context context = GOApplication.getInstance(); return createWaterMakerBitmap(bitmap, watermaker, title, TypefaceHelper.get(context, context.getString(R.string.config_default_font))); } public static Bitmap createWaterMakerBitmap(Bitmap bitmap, Bitmap watermaker, String title, Typeface typeface){ if(!TextUtils.isEmpty(title)) { return createWaterMakerBitmap(bitmap, watermaker, title, getDefaultPaint(), typeface); } return createWaterMakerBitmap(bitmap, watermaker, null, null, null); } public static Bitmap createWaterMakerBitmap(Bitmap bitmap, Bitmap watermaker, String title, Paint paint,Typeface typeface){ if(bitmap == null || (watermaker == null && TextUtils.isEmpty(title))) return bitmap;//nothing need todohere int width = bitmap.getWidth(); int height = bitmap.getHeight(); if(width>0 && height>0) { try { Bitmap newBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888); Canvas canvas = new Canvas(newBitmap); canvas.drawBitmap(bitmap, 0, 0, null);//draw src if(watermaker != null){ canvas.drawBitmap(watermaker, 0, 0, null); } if(!TextUtils.isEmpty(title)){ Paint mpaint = paint; if(mpaint == null){ mpaint = getDefaultPaint(); } if(typeface != null){ mpaint.setTypeface(typeface); } mpaint.setTextAlign(Paint.Align.CENTER); canvas.drawText(title, width/3, height*3/4, mpaint); } canvas.save(Canvas.ALL_SAVE_FLAG); canvas.restore(); return newBitmap; }catch (Throwable e){} } return null; } public static Paint getDefaultPaint(){ Paint paint = new Paint(); paint.setColor(Color.parseColor("#ffff6600"));// #141,141,141 paint.setTextSize(100); paint.setAntiAlias(true); paint.setStrokeWidth(10); paint.setMaskFilter(new BlurMaskFilter(15, BlurMaskFilter.Blur.SOLID)); return paint; } 更多处理 /**圆角处理 * 实际上是在原图片上画了一个圆角遮罩。对于paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); * 方法我刚看到也是一知半解Mode.SRC_IN参数是个画图模式,该类型是指只显 示两层图案的交集部分,且交集部位只显示上层图像。 * 实际就是先画了一个圆角矩形的过滤框,于是形状有了,再将框中的内容填充为图片 * @param bitmap * @param roundPx * @return */ 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 android.graphics.PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN)); canvas.drawBitmap(bitmap, rect, rect, paint); return output; } /** * 灰白处理 就是利用了ColorMatrix 类自带的设置饱和度的方法setSaturation()。 不过其方法内部实现的更深一层是利用颜色矩阵的乘法实现的,对于颜色矩阵的乘法下面还有使用 * @param bmpOriginal * @return */ 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; } /** * 黑白处理 这张图片不同于灰白处理的那张,不同之处是灰白处理虽然没有了颜色, 但是黑白的程度层次依然存在,而此张图片连层次都没有了,只有两个区别十分明显的黑白 颜色。 实现的算法也很简单,对于每个像素的rgb值求平均数,如果高于100算白色,低于100算黑色。 不过感觉100这个标准值太大了,导致图片白色区 域太多,把它降低点可能效果会更好 * @param mBitmap * @return */ public static Bitmap toblackAndwhite(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; } /** * 镜像处理 * 原理就是将原图片反转一下,调整一 下它的颜色作出倒影效果,再将两张图片续加在一起, * 不过如果在反转的同时再利用Matrix加上一些倾斜角度就更好了,不过那样做的话加工后的图片的高度需要同比例计算出来, * 不能简单的相加了,否则就图片大小就容不下现有的像素内容。 * @param bitmap * @return */ 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 android.graphics.PorterDuffXfermode(android.graphics.PorterDuff.Mode.DST_IN)); // Draw a rectangle using the paint with our linear gradient canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint); return bitmapWithReflection; } /** * 加旧处理 * @param bitmap * @return */ public static Bitmap toOldBitmap(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; } /** * 浮雕处理 * 观察浮雕就不难发现,其实浮雕的特点就是在颜色有跳变的地方就刻条痕迹。127,127,127为深灰色, * 近似于石头的颜色,此处取该颜色为底色。算法是将上一个点的rgba值减去当前点的rgba值然后加上127得到当前点的颜色。 * @param mBitmap * @return */ public static Bitmap to_embossment(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; } /** * 油画处理 * 其实油画因为是用画笔画的,彩笔画的时候没有那么精确会将本该这点的颜色滑到另一个点处。 * 算法实现就是取一个一定范围内的随机数,每个点的颜色是该点减去随机数坐标后所得坐标的颜色。 * @param bmpSource * @return */ public static Bitmap to_oilPainting(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; } /** * 模糊处理 * 算法实现其实是取每三点的平均值做为当前点颜色,这样看上去就变得模糊了。 * 这个算法是三点的平均值,如果能够将范围扩大,并且不是单纯的平均值, * 而是加权 平均肯定效果会更好。不过处理速度实在是太慢了,而Muzei这种软件在处理的时候 * ,不仅仅速度特别快,而且还有逐渐变模糊的变化过程,显然人家不是用这 种算法实现的。 * 他们的实现方法正在猜测中,实现后也来更新。 * @param bmpSource * @param Blur * @return */ public static Bitmap blurBitmap(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; } /** * 图片合并 * @param bitmap1 * @param bitmap2 * @param path * @return * @throws FileNotFoundException */ public static Bitmap toJoinbitmap(Bitmap bitmap1,Bitmap bitmap2,String path) throws FileNotFoundException{ Bitmap bitmap3 = Bitmap.createBitmap(bitmap1.getWidth(), bitmap1.getHeight(), bitmap1.getConfig()); Canvas canvas =new Canvas(bitmap3); canvas.drawBitmap(bitmap1,new Matrix(),null); canvas.drawBitmap(bitmap2,120,350,null); //120、350为bitmap2写入点的x、y坐标 //将合并后的bitmap3保存为png图片到本地 FileOutputStream out =new FileOutputStream(path+"/image3.png"); bitmap3.compress(Bitmap.CompressFormat.PNG,90, out); return bitmap3; }
图像平铺处理:
public static void fixBackgroundRepeat(View view) { Drawable bg = view.getBackground(); if (bg != null) { if (bg instanceof BitmapDrawable) { BitmapDrawable bmp = (BitmapDrawable) bg; bmp.mutate(); // make sure that we aren't sharing state anymore bmp.setTileModeXY(TileMode.REPEAT, TileMode.REPEAT); } } }
xml use
<?xml version="1.0" encoding="utf-8"?> <!-- http://stackoverflow.com/questions/1700099/android-how-to-create-a-background-from-pattern --> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/subtlepatterns_escheresque_ste" android:tileMode="repeat" />
//对图像进行相关参数转换,重新形成新的图片数据参数展示形式(Drawble) /** * Create a drawable from file path name. */ public Drawable createFromPath(String pathName) { if (pathName == null) { return null; } BitmapFactory.Options opts = new BitmapFactory.Options(); opts.inJustDecodeBounds = true; opts.inJustDecodeBounds = true; BitmapFactory.decodeFile(pathName, opts); opts.inSampleSize = computeSampleSize(opts, -1, 1280 * 720); opts.inJustDecodeBounds = false; Bitmap bm = BitmapFactory.decodeFile(pathName, opts); if (bm != null) { return drawableFromBitmap(null, bm, null, null, pathName); } return null; } private Drawable drawableFromBitmap(Resources res, Bitmap bm, byte[] np, Rect pad, String srcName) { if (np != null) { return new NinePatchDrawable(res, bm, np, pad, srcName); } return new BitmapDrawable(res, bm); } public int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels); int roundedSize; if (initialSize <= 8) { roundedSize = 1; while (roundedSize < initialSize) { roundedSize <<= 1; } } else { roundedSize = (initialSize + 7) / 8 * 8; } return roundedSize; } private int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { double w = options.outWidth; double h = options.outHeight; int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math .sqrt(w * h / maxNumOfPixels)); int upperBound = (minSideLength == -1) ? 128 : (int) Math.min( Math.floor(w / minSideLength), Math.floor(h / minSideLength)); if (upperBound < lowerBound) { // return the larger one when there is no overlapping zone. return lowerBound; } if ((maxNumOfPixels == -1) && (minSideLength == -1)) { return 1; } else if (minSideLength == -1) { return lowerBound; } else { return upperBound; } }
/**文字保存为png图片 * @param path 文件保存路径 * @param data 保存数据 * @throws FileNotFoundException * */ public static void textToImage(String path,ArrayList<String> data) throws FileNotFoundException{ int height = data.size()*20; //图片高 Bitmap bitmap = Bitmap.createBitmap(270,height, Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); canvas.drawColor(Color.WHITE); //背景颜色 Paint p = new Paint(); p.setColor(Color.BLACK); //画笔颜色 p.setTextSize(15); //画笔粗细 for(int i=0;i<data.size();i++){ canvas.drawText(data.get(i),20,(i+1)*20,p); } FileOutputStream out=new FileOutputStream(path); bitmap.compress(Bitmap.CompressFormat.PNG,90, out); }