声明: 本文是方便自己在以后的项目里使用。
使用场景(图片处理 转格式 拿图片 )
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";
}
}