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;
- }
對圖像進行相關參數轉換,重新形成新的圖片數據參數展示形式(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;
- }
- }
- /**
- * 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;
- }
更多處理
- /**圓角處理
- * 實際上是在原圖片上畫了一個圓角遮罩。對於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;
- }
- /**文字保存爲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);
- }
-