超詳細的圖片處理 工具類

聲明: 本文是方便自己在以後的項目裏使用。

使用場景(圖片處理 轉格式 拿圖片 )


package com.example.testdemo;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader.TileMode;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.util.Log;

/**
 * 獲取圖片的類
 * 
 */
public class DealBitmap {
	private final static String TAG = "com.xiao.hei.img.Util";

	/**
	 * 從src中獲取圖片
	 * 
	 * @param heigth
	 *            縮放後的高度
	 * @param width
	 *            縮放後的寬度
	 * @param src
	 *            src地址
	 * @param context
	 *            上下文
	 * @return
	 */
	public static Bitmap src(int heigth, int width, int src, Context context) {
		if(heigth<=0&&width<=0)
			return src(src, context);
		Options opts = new Options();
		opts.inJustDecodeBounds = true;// 不加載圖片,只是解析圖片
		Bitmap bitmap1 = BitmapFactory.decodeResource(context.getResources(),
				src, opts);
		int bHeigth = opts.outHeight;
		int bWidth = opts.outWidth;
		int multiple=0;
		if(heigth>0&&width>0){
			int heightScale = bHeigth / heigth;
			int widthScale = bWidth / width;
			multiple = heightScale > widthScale ? heightScale : widthScale;
		}else if(heigth>0)
			multiple= bHeigth / heigth;
		else
			multiple=bWidth / width;
		opts.inSampleSize = multiple > 1 ? multiple : 1;
		opts.inJustDecodeBounds = false;
		bitmap1 = BitmapFactory.decodeResource(context.getResources(), src,
				opts);

		return zoom(heigth, width, bitmap1);
	}

	/**
	 * 獲取 src中的圖片
	 * 
	 * @param src
	 * @param context
	 * @return
	 */
	public static Bitmap src(int src, Context context) {
		return BitmapFactory.decodeResource(context.getResources(), src);
	}

	/**
	 * 從文件夾中獲取圖片,這個可能會拿不到圖片
	 * 
	 * @param heigth
	 *            縮放後高度
	 * @param width
	 *            縮放後寬度
	 * @param url
	 *            地址
	 * @return
	 */
	//可以拿app之外的文件地址 但是拿不到app本身的文件地址
	public static Bitmap url(int heigth, int width, String url) {
		if(heigth<=0&&width<=0){
			return url(url);
		}
		Options opts = new Options();
		opts.inJustDecodeBounds = true;
		Bitmap bitmap1 = BitmapFactory.decodeFile(url, opts);
		int bHeigth = opts.outHeight;
		int bWidth = opts.outWidth;
		int multiple=0;
		int heightScale=0;
		int widthScale=0;
		if(width>0&&heigth>0){
			heightScale = bHeigth / heigth;
			widthScale = bWidth / width;
			multiple = heightScale > widthScale ? heightScale : widthScale;
		}else if(width>0){
			multiple = bWidth / width;
		}else{
			multiple = bHeigth / heigth;
		}
		opts.inSampleSize = multiple > 1 ? multiple : 1;
		opts.inJustDecodeBounds = false;
		bitmap1 = BitmapFactory.decodeFile(url, opts);
		return zoom(heigth, width, bitmap1);
	}

	/**
	 * 從文件夾中獲取圖片,這個可能會拿不到圖片
	 * 
	 * @param url
	 * @return
	 */
	public static Bitmap url(String url) {

		return BitmapFactory.decodeFile(url);
	}

	/**
	 * 從文件夾中獲取圖片,這個可能會拿不到圖片
	 * 
	 * @param heigth
	 *            縮放後高度
	 * @param width
	 *            縮放後寬度
	 * @param url
	 *            地址
	 * @param context
	 *            上下文
	 * @return
	 */
	//由於context 所以拿到的url文件地址 是app本身的文件 拿不到app之外的文件地址
	public static Bitmap url(int heigth, int width, String url, Context context) {
		try {
			if(heigth<=0&&width<=0)
				return url(url, context);
			Options opts = new Options();
			opts.inJustDecodeBounds = true;
			Bitmap bitmap1 = BitmapFactory.decodeStream(context
					.getContentResolver().openInputStream(Uri.parse(url)),
					null, opts);
			int bHeigth = opts.outHeight;
			int bWidth = opts.outWidth;
			int multiple=0;
			if(heigth>0&&width>0){
				int heightScale = bHeigth / heigth;
				int widthScale = bWidth / width;
				 multiple = heightScale > widthScale ? heightScale : widthScale;
			}else if(heigth>0)
				multiple=bHeigth / heigth;
			else
				multiple=bWidth / width;
			opts.inSampleSize = multiple > 1 ? multiple : 1;
			opts.inJustDecodeBounds = false;
			bitmap1 = BitmapFactory.decodeStream(context.getContentResolver()
					.openInputStream(Uri.parse(url)), null, opts);
			return zoom(heigth, width, bitmap1);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 從文件夾中獲取圖片,這個可能會拿不到圖片
	 * 
	 * @param url
	 * @param context
	 * @return
	 */
	public static Bitmap url(String url, Context context) {
		try {

			return BitmapFactory.decodeStream(context.getContentResolver()
					.openInputStream(Uri.parse(url)));
		} catch (Exception e) {
			// TODO: handle exception
			return null;
		}
	}

	/**
	 * 字符數組轉化爲圖片
	 * 
	 * @param heigth
	 * @param width
	 * @param buff
	 * @return
	 */
	public static Bitmap bytes2Bitmap(int heigth, int width, byte[] buff) {
		if(width<=0&&heigth<=0)
			return bytes2Bitmap(buff);
		Options opts = new Options();
		opts.inJustDecodeBounds = true;
		Bitmap bitmap1 = BitmapFactory.decodeStream(new ByteArrayInputStream(
				buff), null, opts);
		int bHeigth = opts.outHeight;
		int bWidth = opts.outWidth;
		int multiple =0;
		if(width>0&&heigth>0){
			int heightScale = bHeigth / heigth;
			int widthScale = bWidth / width;
			// 獲取縮略比例 保證最小的能滿足要求
			multiple = heightScale > widthScale ? heightScale : widthScale;
		}else if(heigth>0)
			multiple=bHeigth / heigth;
		else 
			multiple=bWidth / width;
		opts.inSampleSize = multiple > 1 ? multiple : 1;
		opts.inJustDecodeBounds = false;
		bitmap1 = BitmapFactory.decodeStream(new ByteArrayInputStream(buff),
				null, opts);
		return zoom(heigth, width, bitmap1);
	}

	/**
	 * 字符數組轉化爲圖片
	 * 
	 * @param buff
	 * @return
	 */
	public static Bitmap bytes2Bitmap(byte[] buff) {
		return BitmapFactory.decodeStream(new ByteArrayInputStream(buff));
	}

	/**
	 * 將輸入流轉化爲圖片
	 * 
	 * @param heigth
	 * @param width
	 * @param inputStream
	 * @return
	 */
	public static Bitmap inputStream2Bitmap(int heigth, int width,
			InputStream inputStream) {
		if(heigth<=0&&width<=0)
			return inputStream2Bitmap(inputStream);
		byte[] buff =inputStream2byte(inputStream);
		return bytes2Bitmap(heigth, width, buff);
	}

	/**
	 * 將輸入流轉化爲圖片
	 * 
	 * @param inputStream
	 * @return
	 */
	public static Bitmap inputStream2Bitmap(InputStream inputStream) {
		return BitmapFactory.decodeStream(inputStream);
	}
	/**
	 * 用於圖片精確縮放
	 * 
	 * @param heigth
	 *            縮放後的高度
	 * @param width
	 *            縮放後的寬度
	 * @param bmp
	 *            所要縮放的圖片
	 * @return
	 */
	public static Bitmap zoom(float heigth, float width, Bitmap bmp) {
		if(heigth<=0&&width<=0)
			return bmp;
		if (bmp == null) {
			Log.e(TAG, "bmp is null");
			return null;
		}
		Matrix matrix = new Matrix(); // 矩陣,用於圖片比例縮放
		float zoom=0;
		if(heigth>0&&width>0){
			float mW =  width / bmp.getWidth();
			float mH = heigth / bmp.getHeight();
			zoom=mW>mH?mH:mW;
		}else if(heigth>0)
			zoom=heigth / bmp.getHeight();
		else
			zoom=width / bmp.getWidth();
		matrix.postScale(zoom, zoom); // 設置高寬
		bmp = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(),
				matrix, true);
		return bmp;
	}

	/**
	 * 將 Drawable 對象轉化爲bitmap對象
	 * 
	 * @param drawable
	 * @return
	 */
	public static Bitmap drawable2Bitmap(Drawable drawable) {
		int width = drawable.getIntrinsicWidth();
		int height = drawable.getIntrinsicHeight();
		Bitmap bitmap = Bitmap.createBitmap(width, height, drawable
				.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
				: Bitmap.Config.RGB_565);
		Canvas canvas = new Canvas(bitmap);
		drawable.setBounds(0, 0, width, height);
		drawable.draw(canvas);
		return bitmap;

	}

	/**
	 * 獲取圓角圖片
	 * 
	 * @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 PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);

		return output;
	}

	/**
	 * 獲得圓形圖片
	 * 
	 * @param bitmap
	 * @return
	 */
	public static Bitmap getCircleImageBitmap(Bitmap bitmap) {

		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);
		BitmapShader bitmapShader = new BitmapShader(bitmap, TileMode.CLAMP,
				TileMode.CLAMP);
		paint.setShader(bitmapShader);
		int mWidth = Math.min(bitmap.getWidth(), bitmap.getHeight());
		canvas.drawCircle(mWidth / 2, mWidth / 2, mWidth / 2, paint);
		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);
		return output;
	}

	/**
	 * 獲得帶倒影的圖片方法
	 * 
	 * @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 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;
	}

	/**
	 * 懷舊處理
	 * 
	 * @param bmp
	 * @return
	 */
	public static Bitmap nostalgia(Bitmap bmp) {
		/*
		 * 懷舊處理算法即設置新的RGB R=0.393r+0.769g+0.189b G=0.349r+0.686g+0.168b
		 * B=0.272r+0.534g+0.131b
		 */
		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);
		return bitmap;
	}

	/**
	 * 浮雕處理
	 * 
	 * @param bmp
	 * @return
	 */
	public static Bitmap relief(Bitmap bmp) {
		/*
		 * 算法原理:(前一個像素點RGB-當前像素點RGB+127)作爲當前像素點RGB值 在ABC中計算B點浮雕效果(RGB值在0~255)
		 * B.r = C.r - B.r + 127 B.g = C.g - B.g + 127 B.b = C.b - B.b + 127
		 */
		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 = 1; i < height - 1; i++) {
			for (int k = 1; k < width - 1; k++) {
				// 獲取前一個像素顏色
				pixColor = pixels[width * i + k];
				pixR = Color.red(pixColor);
				pixG = Color.green(pixColor);
				pixB = Color.blue(pixColor);
				// 獲取當前像素
				pixColor = pixels[(width * i + k) + 1];
				newR = Color.red(pixColor) - pixR + 127;
				newG = Color.green(pixColor) - pixG + 127;
				newB = Color.blue(pixColor) - pixB + 127;
				newR = Math.min(255, Math.max(0, newR));
				newG = Math.min(255, Math.max(0, newG));
				newB = Math.min(255, Math.max(0, newB));
				pixels[width * i + k] = Color.argb(255, newR, newG, newB);
			}
		}
		bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
		return bitmap;
	}

	/**
	 * 模糊處理
	 * 
	 * @param bmp
	 * @return
	 */
	public static Bitmap fuzzy(Bitmap bmp) {
		/*
		 * 算法原理: 簡單算法將像素周圍八個點包括自身共九個點RGB值分別相加後平均,當前像素點的RGB值 複雜算法採用高斯模糊 高斯矩陣
		 * int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 };
		 * 將九個點的RGB值分別與高斯矩陣中的對應項相乘的和,再除以一個相應的值作爲當前像素點的RGB
		 */
		int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 1 }; // 高斯矩陣
		int delta = 16; // 除以值 值越小圖片會越亮,越大則越暗
		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, newG, newB;
		int pos = 0; // 位置
		int[] pixels = new int[width * height];
		bmp.getPixels(pixels, 0, width, 0, 0, width, height);
		// 循環賦值
		for (int i = 1; i < height - 1; i++) {
			for (int k = 1; k < width - 1; k++) {
				pos = 0;
				newR = 0;
				newG = 0;
				newB = 0;
				for (int m = -1; m <= 1; m++) // 寬不變
				{
					for (int n = -1; n <= 1; n++) // 高先變
					{
						pixColor = pixels[(i + m) * width + k + n];
						pixR = Color.red(pixColor);
						pixG = Color.green(pixColor);
						pixB = Color.blue(pixColor);
						// 3*3像素相加
						newR = newR + (int) (pixR * gauss[pos]);
						newG = newG + (int) (pixG * gauss[pos]);
						newB = newB + (int) (pixB * gauss[pos]);
						pos++;
					}
				}
				newR /= delta;
				newG /= delta;
				newB /= delta;
				newR = Math.min(255, Math.max(0, newR));
				newG = Math.min(255, Math.max(0, newG));
				newB = Math.min(255, Math.max(0, newB));
				pixels[i * width + k] = Color.argb(255, newR, newG, newB);
			}
		}
		bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
		return bitmap;
	}

	/**
	 * 光照效果
	 * 
	 * @param bmp
	 * @return
	 */
	public static Bitmap sunshine(Bitmap bmp) {
		/*
		 * 算法原理:(前一個像素點RGB-當前像素點RGB+127)作爲當前像素點RGB值 在ABC中計算B點浮雕效果(RGB值在0~255)
		 * B.r = C.r - B.r + 127 B.g = C.g - B.g + 127 B.b = C.b - B.b + 127
		 * 光照中心取長寬較小值爲半徑,也可以自定義從左上角射過來
		 */
		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 centerX = width / 2;
		int centerY = height / 2;
		int radius = Math.min(centerX, centerY);
		float strength = 150F; // 光照強度100-150
		int[] pixels = new int[width * height];
		bmp.getPixels(pixels, 0, width, 0, 0, width, height);
		for (int i = 1; i < height - 1; i++) {
			for (int k = 1; k < width - 1; k++) {
				// 獲取前一個像素顏色
				pixColor = pixels[width * i + k];
				pixR = Color.red(pixColor);
				pixG = Color.green(pixColor);
				pixB = Color.blue(pixColor);
				newR = pixR;
				newG = pixG;
				newB = pixB;
				// 計算當前點到光照中心的距離,平面座標系中兩點之間的距離
				int distance = (int) (Math.pow((centerY - i), 2) + Math.pow(
						(centerX - k), 2));
				if (distance < radius * radius) {
					// 按照距離大小計算增強的光照值
					int result = (int) (strength * (1.0 - Math.sqrt(distance)
							/ radius));
					newR = pixR + result;
					newG = newG + result;
					newB = pixB + result;
				}
				newR = Math.min(255, Math.max(0, newR));
				newG = Math.min(255, Math.max(0, newG));
				newB = Math.min(255, Math.max(0, newB));
				pixels[width * i + k] = Color.argb(255, newR, newG, newB);
			}
		}
		bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
		return bitmap;
	}

	/**
	 * 銳化處理
	 * 
	 * @param bmp
	 * @return
	 */
	public static Bitmap sharpen(Bitmap bmp) {
		/*
		 * 銳化基本思想是加強圖像中景物的邊緣和輪廓,使圖像變得清晰 而圖像平滑是使圖像中邊界和輪廓變得模糊
		 * 
		 * 拉普拉斯算子圖像銳化 獲取周圍9個點的矩陣乘以模板9個的矩陣 卷積
		 */
		// 拉普拉斯算子模板 { 0, -1, 0, -1, -5, -1, 0, -1, 0 } { -1, -1, -1, -1, 9, -1,
		// -1, -1, -1 }
		int[] laplacian = new int[] { -1, -1, -1, -1, 9, -1, -1, -1, -1 };
		int width = bmp.getWidth();
		int height = bmp.getHeight();
		Bitmap bitmap = Bitmap.createBitmap(width, height,
				Bitmap.Config.RGB_565);
		int pixR = 0;
		int pixG = 0;
		int pixB = 0;
		int pixColor = 0;
		int newR = 0;
		int newG = 0;
		int newB = 0;
		int idx = 0;
		float alpha = 0.3F; // 圖片透明度
		int[] pixels = new int[width * height];
		bmp.getPixels(pixels, 0, width, 0, 0, width, height);
		// 圖像處理
		for (int i = 1; i < height - 1; i++) {
			for (int k = 1; k < width - 1; k++) {
				idx = 0;
				newR = 0;
				newG = 0;
				newB = 0;
				for (int n = -1; n <= 1; n++) // 取出圖像3*3領域像素
				{
					for (int m = -1; m <= 1; m++) // n行數不變 m列變換
					{
						pixColor = pixels[(i + n) * width + k + m]; // 當前點(i,k)
						pixR = Color.red(pixColor);
						pixG = Color.green(pixColor);
						pixB = Color.blue(pixColor);
						// 圖像像素與對應摸板相乘
						newR = newR + (int) (pixR * laplacian[idx] * alpha);
						newG = newG + (int) (pixG * laplacian[idx] * alpha);
						newB = newB + (int) (pixB * laplacian[idx] * alpha);
						idx++;
					}
				}
				newR = Math.min(255, Math.max(0, newR));
				newG = Math.min(255, Math.max(0, newG));
				newB = Math.min(255, Math.max(0, newB));
				// 賦值
				pixels[i * width + k] = Color.argb(255, newR, newG, newB);
			}
		}
		bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
		return bitmap;
	}

	/**
	 * 冰凍處理
	 * 
	 * @param bmp
	 * @return
	 */
	public static Bitmap ice(Bitmap bmp) {
		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 newColor = 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);
				// 紅色
				newColor = pixR - pixG - pixB;
				newColor = newColor * 3 / 2;
				if (newColor < 0) {
					newColor = -newColor;
				}
				if (newColor > 255) {
					newColor = 255;
				}
				newR = newColor;
				// 綠色
				newColor = pixG - pixB - pixR;
				newColor = newColor * 3 / 2;
				if (newColor < 0) {
					newColor = -newColor;
				}
				if (newColor > 255) {
					newColor = 255;
				}
				newG = newColor;
				// 藍色
				newColor = pixB - pixG - pixR;
				newColor = newColor * 3 / 2;
				if (newColor < 0) {
					newColor = -newColor;
				}
				if (newColor > 255) {
					newColor = 255;
				}
				newB = newColor;
				pixels[width * i + k] = Color.argb(255, newR, newG, newB);
			}
		}
		bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
		return bitmap;
	}

	/**
	 * 素描處理
	 * 
	 * @param bmp
	 * @return
	 */
	public static Bitmap sketch(Bitmap bmp) {
		// 創建新Bitmap
		int width = bmp.getWidth();
		int height = bmp.getHeight();
		int[] pixels = new int[width * height]; // 存儲變換圖像
		int[] linpix = new int[width * height]; // 存儲灰度圖像
		Bitmap bitmap = Bitmap.createBitmap(width, height,
				Bitmap.Config.RGB_565);
		bmp.getPixels(pixels, 0, width, 0, 0, width, height);
		int pixColor = 0;
		int pixR = 0;
		int pixG = 0;
		int pixB = 0;
		// 灰度圖像
		for (int i = 1; i < width - 1; i++) {
			for (int j = 1; j < height - 1; j++) // 拉普拉斯算子模板 { 0, -1, 0, -1, -5,
													// -1, 0, -1, 0
			{
				// 獲取前一個像素顏色
				pixColor = pixels[width * i + j];
				pixR = Color.red(pixColor);
				pixG = Color.green(pixColor);
				pixB = Color.blue(pixColor);
				// 灰度圖像
				int gray = (int) (0.3 * pixR + 0.59 * pixG + 0.11 * pixB);
				linpix[width * i + j] = Color.argb(255, gray, gray, gray);
				// 圖像反向
				gray = 255 - gray;
				pixels[width * i + j] = Color.argb(255, gray, gray, gray);
			}
		}
		int[] copixels = gaussBlur(pixels, width, height, 10, 10 / 3); // 高斯模糊
																		// 採用半徑10
		int[] result = colorDodge(linpix, copixels); // 素描圖像 顏色減淡
		bitmap.setPixels(result, 0, width, 0, 0, width, height);
		return bitmap;
	}

	// 高斯模糊
	public static int[] gaussBlur(int[] data, int width, int height,
			int radius, float sigma) {

		float pa = (float) (1 / (Math.sqrt(2 * Math.PI) * sigma));
		float pb = -1.0f / (2 * sigma * sigma);

		// generate the Gauss Matrix
		float[] gaussMatrix = new float[radius * 2 + 1];
		float gaussSum = 0f;
		for (int i = 0, x = -radius; x <= radius; ++x, ++i) {
			float g = (float) (pa * Math.exp(pb * x * x));
			gaussMatrix[i] = g;
			gaussSum += g;
		}

		for (int i = 0, length = gaussMatrix.length; i < length; ++i) {
			gaussMatrix[i] /= gaussSum;
		}

		// x direction
		for (int y = 0; y < height; ++y) {
			for (int x = 0; x < width; ++x) {
				float r = 0, g = 0, b = 0;
				gaussSum = 0;
				for (int j = -radius; j <= radius; ++j) {
					int k = x + j;
					if (k >= 0 && k < width) {
						int index = y * width + k;
						int color = data[index];
						int cr = (color & 0x00ff0000) >> 16;
						int cg = (color & 0x0000ff00) >> 8;
						int cb = (color & 0x000000ff);

						r += cr * gaussMatrix[j + radius];
						g += cg * gaussMatrix[j + radius];
						b += cb * gaussMatrix[j + radius];

						gaussSum += gaussMatrix[j + radius];
					}
				}

				int index = y * width + x;
				int cr = (int) (r / gaussSum);
				int cg = (int) (g / gaussSum);
				int cb = (int) (b / gaussSum);

				data[index] = cr << 16 | cg << 8 | cb | 0xff000000;
			}
		}

		// y direction
		for (int x = 0; x < width; ++x) {
			for (int y = 0; y < height; ++y) {
				float r = 0, g = 0, b = 0;
				gaussSum = 0;
				for (int j = -radius; j <= radius; ++j) {
					int k = y + j;
					if (k >= 0 && k < height) {
						int index = k * width + x;
						int color = data[index];
						int cr = (color & 0x00ff0000) >> 16;
						int cg = (color & 0x0000ff00) >> 8;
						int cb = (color & 0x000000ff);

						r += cr * gaussMatrix[j + radius];
						g += cg * gaussMatrix[j + radius];
						b += cb * gaussMatrix[j + radius];

						gaussSum += gaussMatrix[j + radius];
					}
				}

				int index = y * width + x;
				int cr = (int) (r / gaussSum);
				int cg = (int) (g / gaussSum);
				int cb = (int) (b / gaussSum);
				data[index] = cr << 16 | cg << 8 | cb | 0xff000000;
			}
		}

		return data;
	}

	// 顏色減淡
	public static int[] colorDodge(int[] baseColor, int[] mixColor) {

		for (int i = 0, length = baseColor.length; i < length; ++i) {
			int bColor = baseColor[i];
			int br = (bColor & 0x00ff0000) >> 16;
			int bg = (bColor & 0x0000ff00) >> 8;
			int bb = (bColor & 0x000000ff);

			int mColor = mixColor[i];
			int mr = (mColor & 0x00ff0000) >> 16;
			int mg = (mColor & 0x0000ff00) >> 8;
			int mb = (mColor & 0x000000ff);

			int nr = colorDodgeFormular(br, mr);
			int ng = colorDodgeFormular(bg, mg);
			int nb = colorDodgeFormular(bb, mb);

			baseColor[i] = nr << 16 | ng << 8 | nb | 0xff000000;
		}
		return baseColor;
	}

	private static int colorDodgeFormular(int base, int mix) {

		int result = base + (base * mix) / (255 - mix);
		result = result > 255 ? 255 : result;
		return result;

	}

	/**
	 * 圖片合成
	 * 
	 * @param bm
	 * @param bmp
	 */
	public static Bitmap addFrameToImage(Bitmap bm, Bitmap bmp) // bmp原圖(前景)
																// bm資源圖片(背景)
	{
		Bitmap drawBitmap = Bitmap.createBitmap(bmp.getWidth(),
				bmp.getHeight(), bmp.getConfig());
		Canvas canvas = new Canvas(drawBitmap);
		Paint paint = new Paint();
		canvas.drawBitmap(bmp, 0, 0, paint);
		paint.setXfermode(new PorterDuffXfermode(
				android.graphics.PorterDuff.Mode.LIGHTEN));
		// 對邊框進行縮放
		int w = bm.getWidth();
		int h = bm.getHeight();
		// 縮放比 如果圖片尺寸超過邊框尺寸 會自動匹配
		float scaleX = bmp.getWidth() * 1F / w;
		float scaleY = bmp.getHeight() * 1F / h;
		Matrix matrix = new Matrix();
		matrix.postScale(scaleX, scaleY); // 縮放圖片
		Bitmap copyBitmap = Bitmap.createBitmap(bm, 0, 0, w, h, matrix, true);
		canvas.drawBitmap(copyBitmap, 0, 0, paint);
		return drawBitmap;
	}

	/**
	 * 圖片合成
	 * 
	 * @param frameBitmap
	 * @param bmp
	 * @return
	 */
	public static Bitmap addFrameToImageTwo(Bitmap frameBitmap, Bitmap bmp) // bmp原圖
																			// frameBitmap資源圖片(邊框)
	{
		// bmp原圖 創建新位圖
		int width = bmp.getWidth();
		int height = bmp.getHeight();
		Bitmap drawBitmap = Bitmap.createBitmap(width, height, Config.RGB_565);
		// 對邊框進行縮放
		int w = frameBitmap.getWidth();
		int h = frameBitmap.getHeight();
		float scaleX = width * 1F / w; // 縮放比 如果圖片尺寸超過邊框尺寸 會自動匹配
		float scaleY = height * 1F / h;
		Matrix matrix = new Matrix();
		matrix.postScale(scaleX, scaleY); // 縮放圖片
		Bitmap copyBitmap = Bitmap.createBitmap(frameBitmap, 0, 0, w, h,
				matrix, true);

		int pixColor = 0;
		int layColor = 0;
		int newColor = 0;

		int pixR = 0;
		int pixG = 0;
		int pixB = 0;
		int pixA = 0;

		int newR = 0;
		int newG = 0;
		int newB = 0;
		int newA = 0;

		int layR = 0;
		int layG = 0;
		int layB = 0;
		int layA = 0;

		float alpha = 0.8F;
		float alphaR = 0F;
		float alphaG = 0F;
		float alphaB = 0F;

		for (int i = 0; i < width; i++) {
			for (int k = 0; k < height; k++) {
				pixColor = bmp.getPixel(i, k);
				layColor = copyBitmap.getPixel(i, k);
				// 獲取原圖片的RGBA值
				pixR = Color.red(pixColor);
				pixG = Color.green(pixColor);
				pixB = Color.blue(pixColor);
				pixA = Color.alpha(pixColor);
				// 獲取邊框圖片的RGBA值
				layR = Color.red(layColor);
				layG = Color.green(layColor);
				layB = Color.blue(layColor);
				layA = Color.alpha(layColor);
				// 顏色與純黑色相近的點
				if (layR < 20 && layG < 20 && layB < 20) {
					alpha = 1F;
				} else {
					alpha = 0.3F;
				}
				alphaR = alpha;
				alphaG = alpha;
				alphaB = alpha;
				// 兩種顏色疊加
				newR = (int) (pixR * alphaR + layR * (1 - alphaR));
				newG = (int) (pixG * alphaG + layG * (1 - alphaG));
				newB = (int) (pixB * alphaB + layB * (1 - alphaB));
				layA = (int) (pixA * alpha + layA * (1 - alpha));
				// 值在0~255之間
				newR = Math.min(255, Math.max(0, newR));
				newG = Math.min(255, Math.max(0, newG));
				newB = Math.min(255, Math.max(0, newB));
				newA = Math.min(255, Math.max(0, layA));
				// 繪製
				newColor = Color.argb(newA, newR, newG, newB);
				drawBitmap.setPixel(i, k, newColor);
			}
		}
		return drawBitmap;
	}
	/**
	 * 壓縮圖片到指定大小或以下
	 * 
	 * @return
	 */
	@SuppressLint("NewApi")
	public static Bitmap compression(long size, String url) {
		Options opts = new Options();
		opts.inJustDecodeBounds = false;
		Bitmap bitmap = BitmapFactory.decodeFile(url, opts);
		return compression(size, bitmap);
	}

	/**
	 * 壓縮圖片到指定大小
	 * 
	 * @param size
	 * @param bitmap
	 * @return
	 */
	@SuppressLint("NewApi")
	public static Bitmap compression(long size, Bitmap bitmap) {
		int bs = 0;
		if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR1) {
			bs = bitmap.getByteCount();
		} else
			bs = bitmap.getRowBytes() * bitmap.getHeight();
		int proportion = 1;
		while (bs >= size * proportion) {
			proportion = proportion << 1;
		}
		if (proportion == 1)
			return bitmap;
		Matrix matrix = new Matrix();
		float p = proportion * 0.5f;
		float sx = 1 / p;
		float sy = 1 / p;
		matrix.postScale(sx, sy);
		return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
				bitmap.getHeight(), matrix, true);
	}
	/**
	 * 將輸入流轉換爲byte數組
	 * 
	 * @param is
	 * @return
	 */
	public static byte[] inputStream2byte(InputStream is) {
		try {
			// TODO Auto-generated method stub
			ByteArrayOutputStream bos = new ByteArrayOutputStream();
			int len = 0;
			byte[] buffer = new byte[1024];
			while ((len = is.read(buffer)) != -1) {
				bos.write(buffer, 0, len);
			}
			bos.flush();
			byte[] arr = bos.toByteArray();
			bos.close();
			is.close();
//			new DashPathEffect(intervals, phase)
			return arr;
		} catch (Exception e) {
			// TODO: handle exception
			return e.getMessage().getBytes();
		}
	}

	/**
	 * 將圖像轉換爲 byte數組
	 * 
	 * @param bmp
	 * @return
	 */
	public static byte[] bitmap2byte(Bitmap bmp) {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			bmp.compress(Bitmap.CompressFormat.PNG, 100, baos);
			byte[] b = baos.toByteArray();
			baos.close();
			return b;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 將圖像轉換爲輸入流
	 * 
	 * @param bmp
	 * @return
	 */
	public static InputStream bitmap2InputStream(Bitmap bmp) {
		byte[] b = bitmap2byte(bmp);
		if (b != null)
			return new ByteArrayInputStream(b);
		return null;
	}

	/**
	 * 將圖片轉換爲文件
	 * 
	 * @param bmp
	 * @return
	 */
	public static String bitmap2File(Bitmap bmp) {
		try {
			if (android.os.Environment.getExternalStorageState().equals(
					android.os.Environment.MEDIA_MOUNTED)) {
				File file = new File(Environment.getExternalStorageDirectory(),
						getPhotoFileName());
				file.createNewFile();

				// Toast.makeText(MainActivity.this,"圖片地址------"+bitmap.compress(Bitmap.CompressFormat.PNG,
				// 70, out) , 2).show();
				FileOutputStream out = new FileOutputStream(file);
				if (bmp.compress(Bitmap.CompressFormat.PNG, 30, out)) {
					out.flush();
					out.close();
					return file.getPath();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	private static String getPhotoFileName() {
		// TODO Auto-generated method stub
		Date date = new Date(System.currentTimeMillis());
		SimpleDateFormat dateFormat = new SimpleDateFormat(
				"'IMG'_yyyyMMdd_HHmmss");
		return dateFormat.format(date) + ".jpg";
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章