/**
* 图片缩放
*
* @param pBitmap
* @param pW
* @param pH
* @return
*/
public static Bitmap zoomBitmap(Bitmap pBitmap, int pW, int pH) {
int _width = pBitmap.getWidth();// 获取原图的宽
int _heigth = pBitmap.getHeight();// 获取原图的高
// 获取缩放比
float _ScaleW = (float) pW / _width;
float _ScaleH = (float) pH / _heigth;
Matrix _Matrix = new Matrix();// 创建Matrix矩阵对象
_Matrix.setScale(_ScaleW, _ScaleH);// 设置宽高的缩放比
return Bitmap.createBitmap(pBitmap, 0, 0, _width, _heigth, _Matrix,
true);// 对截原图的0,0坐标到_width,_heigth的图片进行_Matrix处理
}
/**
* 图片圆角
*
* @param pBitmap
* @param pRoundpx
* @return
*/
public static Bitmap RoundedCornerBitmap(Bitmap pBitmap, float pRoundpx) {
Bitmap _NewBitmap = Bitmap.createBitmap(pBitmap.getWidth(),
pBitmap.getHeight(), Config.ARGB_8888); // 创建图片画布大小
Canvas _Canvas = new Canvas(_NewBitmap); // 创建画布
_Canvas.drawARGB(0, 0, 0, 0); // 设置画布透明
Paint _Paint = new Paint(); // 创建画笔
_Paint.setAntiAlias(true); // 抗锯齿
_Paint.setColor(0xff000000);// 画笔颜色透明
// 画与原图片大小一致的圆角矩形
Rect _Rect = new Rect(0, 0, pBitmap.getWidth(), pBitmap.getHeight());
RectF _RectF = new RectF(_Rect);
_Canvas.drawRoundRect(_RectF, pRoundpx, pRoundpx, _Paint);
_Paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));// 设置下面张图片与上面张图片的交互模式
_Canvas.drawBitmap(pBitmap, _Rect, _Rect, _Paint);// 画原图到画布
return _NewBitmap;
}
/**
* 图片倒影
*
* @param pBitmap
* @return
*/
public static Bitmap ReflectionImageWithOrigin(Bitmap pBitmap) {
// 创建等宽,高+高/5的画布
Bitmap _NewBitmap = Bitmap
.createBitmap(pBitmap.getWidth(),
pBitmap.getHeight() + pBitmap.getHeight() / 5,
Config.ARGB_8888);
Canvas _Canvas = new Canvas(_NewBitmap);
_Canvas.drawBitmap(pBitmap, 0, 0, null);// 画上原图
// 原图翻转,
Matrix _Matrix = new Matrix();
_Matrix.preScale(1, -1);
Bitmap _Bitmap = Bitmap.createBitmap(pBitmap, 0, 0, pBitmap.getWidth(),
pBitmap.getHeight(), _Matrix, true);
// 在剩余画布上画上翻转图
_Canvas.drawBitmap(_Bitmap, 0, pBitmap.getHeight(), null);
Paint _Paint = new Paint();
// 实现图片的渐变效果
LinearGradient shader = new LinearGradient(0, pBitmap.getHeight(), 0,
_NewBitmap.getHeight(), 0x70ffffff, 0x00ffffff, TileMode.CLAMP);
_Paint.setShader(shader);
_Paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
_Canvas.drawRect(0, pBitmap.getHeight(), pBitmap.getWidth(),
_NewBitmap.getHeight(), _Paint);
return _NewBitmap;
}
//首先:底片
public Bitmap handleNegative(Bitmap bt) {
int width = bt.getWidth();
int height = bt.getHeight();
int color;
int r, g, b, a;
Bitmap bmp = Bitmap.createBitmap(width, height, Config.ARGB_8888);
// 存放原来的像素值
int oldPix[] = new int[width * height];
int newPix[] = new int[width * height];
// 将像素值赋值给oldpix;
bt.getPixels(oldPix, 0, width, 0, 0, width, height);
// 循环取出每个像素,并对其进行更改
for (int i = 0; i < oldPix.length; i++) {
// 分别取出这个像素值对应的RGB值
color = oldPix[i];
r = Color.red(color);
g = Color.green(color);
b = Color.red(color);
a = Color.alpha(color);
// 应用底片变换公式
r = 255 - r;
g = 255 - g;
b = 255 - b;
// 检查越界
if (r < 0) {
r = 0;
} else if (r > 255) {
r = 255;
}
if (g < 0) {
g = 0;
} else if (g > 255) {
g = 255;
}
if (b < 0) {
b = 0;
} else if (b > 255) {
b = 255;
}
newPix[i] = Color.argb(a, r, g, b);
}
bmp.setPixels(newPix, 0, width, 0, 0, width, height);
return bmp;
}
其次:怀旧
public Bitmap handleOld(Bitmap bt) {
int width = bt.getWidth();
int height = bt.getHeight();
int color;
int r, g, b, a;
Bitmap bmp = Bitmap.createBitmap(width, height, Config.ARGB_8888);
// 存放原来的像素值
int oldPix[] = new int[width * height];
int newPix[] = new int[width * height];
// 将像素值赋值给oldpix;
bt.getPixels(oldPix, 0, width, 0, 0, width, height);
// 循环取出每个像素,并对其进行更改
for (int i = 0; i < oldPix.length; i++) {
// 分别取出这个像素值对应的RGB值
color = oldPix[i];
r = Color.red(color);
g = Color.green(color);
b = Color.red(color);
a = Color.alpha(color);
// 应用底片变换公式
r = (int) (0.393*r+0.769*r+0.189*r);
g = (int) (0.349*g+0.686*g+0.189*g);
b = (int) (0.272*b+0.534*b+0.131*b);
// 检查越界
if (r < 0) {
r = 0;
} else if (r > 255) {
r = 255;
}
if (g < 0) {
g = 0;
} else if (g > 255) {
g = 255;
}
if (b < 0) {
b = 0;
} else if (b > 255) {
b = 255;
}
newPix[i] = Color.argb(a, r, g, b);
}
bmp.setPixels(newPix, 0, width, 0, 0, width, height);
return bmp;
}
最后:雕塑
public Bitmap handleRelief(Bitmap bt) {
int width = bt.getWidth();
int height = bt.getHeight();
int color,color1;
int r, g, b, a;
int r1,g1,b1;
Bitmap bmp = Bitmap.createBitmap(width, height, Config.ARGB_8888);
// 存放原来的像素值
int oldPix[] = new int[width * height];
int newPix[] = new int[width * height];
// 将像素值赋值给oldpix;
bt.getPixels(oldPix, 0, width, 0, 0, width, height);
// 循环取出每个像素,并对其进行更改
for (int i = 0; i < oldPix.length; i++) {
// 分别取出这个像素值对应的RGB值
color = oldPix[i];
r = Color.red(color);
g = Color.green(color);
b = Color.red(color);
a = Color.alpha(color);
//注意这里的处理:防止数组越界
color1 = oldPix[i==0?0:i-1];
r1 = Color.red(color1);
g1 = Color.green(color1);
b1 = Color.red(color1);
// 应用底片变换公式
r = r1-r+127;
g = g1-g+127;
b = b1-b+127;
// 检查越界
if (r < 0) {
r = 0;
} else if (r > 255) {
r = 255;
}
if (g < 0) {
g = 0;
} else if (g > 255) {
g = 255;
}
if (b < 0) {
b = 0;
} else if (b > 255) {
b = 255;
}
newPix[i] = Color.argb(a, r, g, b);
}
bmp.setPixels(newPix, 0, width, 0, 0, width, height);
return bmp;
}
//图片二值化
public Bitmap binarization(Bitmap img) {
width = img.getWidth();
height = img.getHeight();
int area = width * height;
int gray[][] = new int[width][height];
int average = 0;// 灰度平均值
int graysum = 0;
int graymean = 0;
int grayfrontmean = 0;
int graybackmean = 0;
int pixelGray;
int front = 0;
int back = 0;
int[] pix = new int[width * height];
img.getPixels(pix, 0, width, 0, 0, width, height);
for (int i = 1; i < width; i++) { // 不算边界行和列,为避免越界
for (int j = 1; j < height; j++) {
int x = j * width + i;
int r = (pix[x] >> 16) & 0xff;
int g = (pix[x] >> 8) & 0xff;
int b = pix[x] & 0xff;
pixelGray = (int) (0.3 * r + 0.59 * g + 0.11 * b);// 计算每个坐标点的灰度
gray[i][j] = (pixelGray << 16) + (pixelGray << 8) + (pixelGray);
graysum += pixelGray;
}
}
graymean = (int) (graysum / area);// 整个图的灰度平均值
average = graymean;
Log.i(TAG,"Average:"+average);
for (int i = 0; i < width; i++) // 计算整个图的二值化阈值
{
for (int j = 0; j < height; j++) {
if (((gray[i][j]) & (0x0000ff)) < graymean) {
graybackmean += ((gray[i][j]) & (0x0000ff));
back++;
} else {
grayfrontmean += ((gray[i][j]) & (0x0000ff));
front++;
}
}
}
int frontvalue = (int) (grayfrontmean / front);// 前景中心
int backvalue = (int) (graybackmean / back);// 背景中心
float G[] = new float[frontvalue - backvalue + 1];// 方差数组
int s = 0;
Log.i(TAG,"Front:"+front+"**Frontvalue:"+frontvalue+"**Backvalue:"+backvalue);
for (int i1 = backvalue; i1 < frontvalue + 1; i1++)// 以前景中心和背景中心为区间采用大津法算法(OTSU算法)
{
back = 0;
front = 0;
grayfrontmean = 0;
graybackmean = 0;
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
if (((gray[i][j]) & (0x0000ff)) < (i1 + 1)) {
graybackmean += ((gray[i][j]) & (0x0000ff));
back++;
} else {
grayfrontmean += ((gray[i][j]) & (0x0000ff));
front++;
}
}
}
grayfrontmean = (int) (grayfrontmean / front);
graybackmean = (int) (graybackmean / back);
G[s] = (((float) back / area) * (graybackmean - average)
* (graybackmean - average) + ((float) front / area)
* (grayfrontmean - average) * (grayfrontmean - average));
s++;
}
float max = G[0];
int index = 0;
for (int i = 1; i < frontvalue - backvalue + 1; i++) {
if (max < G[i]) {
max = G[i];
index = i;
}
}
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
int in = j * width + i;
if (((gray[i][j]) & (0x0000ff)) < (index + backvalue)) {
pix[in] = Color.rgb(0, 0, 0);
} else {
pix[in] = Color.rgb(255, 255, 255);
}
}
}
Bitmap temp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
temp.setPixels(pix, 0, width, 0, 0, width, height);
return temp;
}
/**
* 图片锐化(拉普拉斯变换)
* @param bmp
* @return
*/
private Bitmap sharpenImageAmeliorate(Bitmap bmp)
{
long start = System.currentTimeMillis();
// 拉普拉斯矩阵
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, length = height - 1; i < length; i++)
{
for (int k = 1, len = width - 1; k < len; k++)
{
idx = 0;
for (int m = -1; m <= 1; m++)
{
for (int n = -1; n <= 1; n++)
{
pixColor = pixels[(i + n) * width + k + m];
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);
newR = 0;
newG = 0;
newB = 0;
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
long end = System.currentTimeMillis();
Log.d("may", "used time="+(end - start));
return bitmap;
}
//高斯模糊
public static Bitmap doBlur(Bitmap sentBitmap, int radius,
boolean canReuseInBitmap) {
Bitmap bitmap;
if (canReuseInBitmap) {
bitmap = sentBitmap;
} else {
bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
}
if (radius < 1) {
return (null);
}
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int[] pix = new int[w * h];
bitmap.getPixels(pix, 0, w, 0, 0, w, h);
int wm = w - 1;
int hm = h - 1;
int wh = w * h;
int div = radius + radius + 1;
int r[] = new int[wh];
int g[] = new int[wh];
int b[] = new int[wh];
int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
int vmin[] = new int[Math.max(w, h)];
int divsum = (div + 1) >> 1;
divsum *= divsum;
int dv[] = new int[256 * divsum];
for (i = 0; i < 256 * divsum; i++) {
dv[i] = (i / divsum);
}
yw = yi = 0;
int[][] stack = new int[div][3];
int stackpointer;
int stackstart;
int[] sir;
int rbs;
int r1 = radius + 1;
int routsum, goutsum, boutsum;
int rinsum, ginsum, binsum;
for (y = 0; y < h; y++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
for (i = -radius; i <= radius; i++) {
p = pix[yi + Math.min(wm, Math.max(i, 0))];
sir = stack[i + radius];
sir[0] = (p & 0xff0000) >> 16;
sir[1] = (p & 0x00ff00) >> 8;
sir[2] = (p & 0x0000ff);
rbs = r1 - Math.abs(i);
rsum += sir[0] * rbs;
gsum += sir[1] * rbs;
bsum += sir[2] * rbs;
if (i > 0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
} else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}
}
stackpointer = radius;
for (x = 0; x < w; x++) {
r[yi] = dv[rsum];
g[yi] = dv[gsum];
b[yi] = dv[bsum];
rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;
stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];
routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];
if (y == 0) {
vmin[x] = Math.min(x + radius + 1, wm);
}
p = pix[yw + vmin[x]];
sir[0] = (p & 0xff0000) >> 16;
sir[1] = (p & 0x00ff00) >> 8;
sir[2] = (p & 0x0000ff);
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
rsum += rinsum;
gsum += ginsum;
bsum += binsum;
stackpointer = (stackpointer + 1) % div;
sir = stack[(stackpointer) % div];
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];
yi++;
}
yw += w;
}
for (x = 0; x < w; x++) {
rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
yp = -radius * w;
for (i = -radius; i <= radius; i++) {
yi = Math.max(0, yp) + x;
sir = stack[i + radius];
sir[0] = r[yi];
sir[1] = g[yi];
sir[2] = b[yi];
rbs = r1 - Math.abs(i);
rsum += r[yi] * rbs;
gsum += g[yi] * rbs;
bsum += b[yi] * rbs;
if (i > 0) {
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
} else {
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
}
if (i < hm) {
yp += w;
}
}
yi = x;
stackpointer = radius;
for (y = 0; y < h; y++) {
// Preserve alpha channel: ( 0xff000000 & pix[yi] )
pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16)
| (dv[gsum] << 8) | dv[bsum];
rsum -= routsum;
gsum -= goutsum;
bsum -= boutsum;
stackstart = stackpointer - radius + div;
sir = stack[stackstart % div];
routsum -= sir[0];
goutsum -= sir[1];
boutsum -= sir[2];
if (x == 0) {
vmin[y] = Math.min(y + r1, hm) * w;
}
p = x + vmin[y];
sir[0] = r[p];
sir[1] = g[p];
sir[2] = b[p];
rinsum += sir[0];
ginsum += sir[1];
binsum += sir[2];
rsum += rinsum;
gsum += ginsum;
bsum += binsum;
stackpointer = (stackpointer + 1) % div;
sir = stack[stackpointer];
routsum += sir[0];
goutsum += sir[1];
boutsum += sir[2];
rinsum -= sir[0];
ginsum -= sir[1];
binsum -= sir[2];
yi += w;
}
}
bitmap.setPixels(pix, 0, w, 0, 0, w, h);
return (bitmap);
}
//图片灰度化
private Bitmap convertToGrayscale(Bitmap bitmap) {
ColorMatrix colorMatrix = new ColorMatrix();
colorMatrix.setSaturation(0);
Paint paint = new Paint();
ColorMatrixColorFilter cmcf = new ColorMatrixColorFilter(colorMatrix);
paint.setColorFilter(cmcf);
Bitmap result = Bitmap.createBitmap(bitmap.getWidth(), bitmap
.getHeight(), Bitmap.Config.RGB_565);
Canvas drawingCanvas = new Canvas(result);
Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
Rect dst = new Rect(src);
drawingCanvas.drawBitmap(bitmap, src, dst, paint);
return result;
}
//线性灰度化
public Bitmap lineGrey(Bitmap image)
{
//得到图像的宽度和长度
int width = image.getWidth();
int height = image.getHeight();
//创建线性拉升灰度图像
Bitmap linegray = null;
linegray = image.copy(Bitmap.Config.ARGB_8888, true);
//依次循环对图像的像素进行处理
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
//得到每点的像素值
int col = image.getPixel(i, j);
int alpha = col & 0xFF000000;
int red = (col & 0x00FF0000) >> 16;
int green = (col & 0x0000FF00) >> 8;
int blue = (col & 0x000000FF);
// 增加了图像的亮度
red = (int) (1.1 * red + 30);
green = (int) (1.1 * green + 30);
blue = (int) (1.1 * blue + 30);
//对图像像素越界进行处理
if (red >= 255)
{
red = 255;
}
if (green >= 255) {
green = 255;
}
if (blue >= 255) {
blue = 255;
}
// 新的ARGB
int newColor = alpha | (red << 16) | (green << 8) | blue;
//设置新图像的RGB值
linegray.setPixel(i, j, newColor);
}
}
return linegray;
}