聲明: 本文是方便自己在以後的項目裏使用。
使用場景(圖片處理 轉格式 拿圖片 )
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";
}
}