美文网首页
一些常用的图像处理方法

一些常用的图像处理方法

作者: 学习不断 | 来源:发表于2018-01-11 17:07 被阅读373次

public class ImageProcessHelper {

////////////////////////////////////////////////////////////////////

    private ImageProcessHelper() {

}

private static class HelperTemp {

private static ImageProcessHelperhelper =new ImageProcessHelper();

}

/**

* 获取处理实例

* Get ImageProcessHelper instance by single

*

    * @return ImageProcessHelper

*/

    public static ImageProcessHelper getInstance() {

return HelperTemp.helper;

}

///////////////////////////////////////////////////////////////////

//////////////////////////////图片位置//////////////////////////////

/**

* 位置 上下左右中 左上角 左下角 右上角 右下角 中间

* */

    public enum Position {

LEFT,

RIGHT,

TOP,

BOTTOM,

CENTRE,

LEFT_UP,

LEFT_DOWN,

RIGHT_UP,

RIGHT_DOWN,

CENTER;

}

/**

* 图片格式

* */

    public enum Format {

JPEG,

PNG,

WEBP;

}

/**

* Bitmap图片转换成圆角

*

    * @param mBitmapSrc 图片源

    * @param roundPx    float

    * @return Bitmap

*/

    public Bitmap convert2RoundedCorner(Bitmap mBitmapSrc,float roundPx) {

Bitmap newBitmap = Bitmap.createBitmap(mBitmapSrc.getWidth(), mBitmapSrc.getHeight(),

Bitmap.Config.ARGB_8888);

// 得到画布

        Canvas canvas =new Canvas(newBitmap);

final int color =0xff424242;

final Paint paint =new Paint();

final Rect rect =new Rect(0,0, mBitmapSrc.getWidth(), mBitmapSrc.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(PorterDuff.Mode.SRC_IN));

canvas.drawBitmap(mBitmapSrc, rect, rect, paint);

return newBitmap;

}

/**

* Bitmap图片灰度化处理

*

    * @param mBitmapSrc 图片源

    * @return Bitmap

*/

    public Bitmap bitmap2Gray(Bitmap mBitmapSrc) {

// 得到图片的长和宽

        int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.getHeight();

// 创建目标灰度图像

        Bitmap bmpGray =null;

bmpGray = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);

// 创建画布

        Canvas c =new Canvas(bmpGray);

Paint paint =new Paint();

ColorMatrix cm =new ColorMatrix();

cm.setSaturation(0);

ColorMatrixColorFilter f =new ColorMatrixColorFilter(cm);

paint.setColorFilter(f);

c.drawBitmap(mBitmapSrc,0,0, paint);

return bmpGray;

}

//另一种灰度

    public Bitmap convertGreyImgByFloyd(Bitmap img) {

int width = img.getWidth();//获取位图的宽

        int height = img.getHeight();//获取位图的高

        int[] pixels =new int[width * height];//通过位图的大小创建像素点数组

        img.getPixels(pixels,0, width,0,0, width, height);

int[] gray=new int[height*width];

for (int i =0; i < height; i++) {

for (int j =0; j < width; j++) {

int grey = pixels[width * i + j];

int red = ((grey  &0x00FF0000 ) >>16);

gray[width*i+j]=red;

}

}

int e=0;

for (int i =0; i < height; i++) {

for (int j =0; j < width; j++) {

int g=gray[width*i+j];

if (g>=128) {

pixels[width*i+j]=0xffffffff;

e=g-255;

}else {

pixels[width*i+j]=0xff000000;

e=g-0;

}

if (j

//右边像素处理

                    gray[width*i+j+1]+=3*e/8;

//下

                    gray[width*(i+1)+j]+=3*e/8;

//右下

                    gray[width*(i+1)+j+1]+=e/4;

}else if (j==width-1&&i

//下方像素处理

                    gray[width*(i+1)+j]+=3*e/8;

}else if (j

//右边像素处理

                    gray[width*(i)+j+1]+=e/4;

}

}

}

Bitmap mBitmap=Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);

mBitmap.setPixels(pixels,0, width,0,0, width, height);

return mBitmap;

}

/**

* 图片线性灰度处理

*

    * @param mBitmapSrc 图片源

    * @return Bitmap

*/

    public Bitmap bitmap2LineGrey(Bitmap mBitmapSrc) {

// 得到图像的宽度和长度

        int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.getHeight();

// 创建线性拉升灰度图像

        Bitmap bitmap = mBitmapSrc.copy(Bitmap.Config.ARGB_8888,true);

// 依次循环对图像的像素进行处理

        for (int i =0; i < width; i++) {

for (int j =0; j < height; j++) {

// 得到每点的像素值

                int col = mBitmapSrc.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值

                bitmap.setPixel(i, j, newColor);

}

}

return bitmap;

}

/**

* 图像二值化处理

*

    * @param mBitmapSrc 图片源

    * @return Bitmap

*/

    public Bitmap gray2Binary(Bitmap mBitmapSrc) {

// 得到图形的宽度和长度

        int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.getHeight();

// 创建二值化图像

        Bitmap binarybm =null;

binarybm = mBitmapSrc.copy(Bitmap.Config.ARGB_8888,true);

// 依次循环,对图像的像素进行处理

        for (int i =0; i < width; i++) {

for (int j =0; j < height; j++) {

// 得到当前像素的值

                int col = binarybm.getPixel(i, j);

// 得到alpha通道的值

                int alpha = col &0xFF000000;

// 得到图像的像素RGB的值

                int red = (col &0x00FF0000) >>16;

int green = (col &0x0000FF00) >>8;

int blue = (col &0x000000FF);

// 用公式X = 0.3×R+0.59×G+0.11×B计算出X代替原来的RGB

                int gray = (int) ((float) red *0.3 + (float) green *0.59 + (float) blue *0.11);

// 对图像进行二值化处理

                if (gray <=95) {

gray =0;

}else {

gray =255;

}

// 新的ARGB

                int newColor = alpha | (gray <<16) | (gray <<8) | gray;

// 设置新图像的当前像素值

                binarybm.setPixel(i, j, newColor);

}

}

return binarybm;

}

/**

* 高斯模糊

*

    * @param mBitmapSrc 图片源

    * @return Bitmap

*/

    public Bitmap convertToBlur(Bitmap mBitmapSrc) {

// 高斯矩阵

        int[] gauss =new int[]{1,2,1,2,4,2,1,2,1};

int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.getHeight();

Bitmap newBmp = 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 delta =16;// 值越小图片会越亮,越大则越暗

        int idx =0;

int[] pixels =new int[width * height];

mBitmapSrc.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 + m) * width + k + n];

pixR = Color.red(pixColor);

pixG = Color.green(pixColor);

pixB = Color.blue(pixColor);

newR = newR + pixR * gauss[idx];

newG = newG + pixG * gauss[idx];

newB = newB + pixB * gauss[idx];

idx++;

}

}

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);

newR =0;

newG =0;

newB =0;

}

}

newBmp.setPixels(pixels,0, width,0,0, width, height);

return newBmp;

}

/**

* 素描效果

*

    * @param BitmapSrc 图片源

    * @return Bitmap

*/

    public Bitmap convertToSketch(Bitmap BitmapSrc) {

Bitmap mBitmapSrc = BitmapSrc.copy(Bitmap.Config.ARGB_8888,true);

int pos, row, col, clr;

int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.getHeight();

int[] pixSrc =new int[width * height];

int[] pixNvt =new int[width * height];

// 先对图象的像素处理成灰度颜色后再取反

        mBitmapSrc.getPixels(pixSrc,0, width,0,0, width, height);

for (row =0; row < height; row++) {

for (col =0; col < width; col++) {

pos = row * width + col;

pixSrc[pos] = (Color.red(pixSrc[pos])

+ Color.green(pixSrc[pos]) + Color.blue(pixSrc[pos])) /3;

pixNvt[pos] =255 - pixSrc[pos];

}

}

// 对取反的像素进行高斯模糊, 强度可以设置,暂定为5.0

        gaussGray(pixNvt,5.0,5.0, width, height);

// 灰度颜色和模糊后像素进行差值运算

        for (row =0; row < height; row++) {

for (col =0; col < width; col++) {

pos = row * width + col;

clr = pixSrc[pos] <<8;

clr /=256 - pixNvt[pos];

clr = Math.min(clr,255);

pixSrc[pos] = Color.rgb(clr, clr, clr);

}

}

mBitmapSrc.setPixels(pixSrc,0, width,0,0, width, height);

return mBitmapSrc;

}

private int gaussGray(int[] psrc,double horz,double vert,

int width,int height) {

int[] dst, src;

double[] n_p, n_m, d_p, d_m, bd_p, bd_m;

double[] val_p, val_m;

int i, j, t, k, row, col, terms;

int[] initial_p, initial_m;

double std_dev;

int row_stride = width;

int max_len = Math.max(width, height);

int sp_p_idx, sp_m_idx, vp_idx, vm_idx;

val_p =new double[max_len];

val_m =new double[max_len];

n_p =new double[5];

n_m =new double[5];

d_p =new double[5];

d_m =new double[5];

bd_p =new double[5];

bd_m =new double[5];

src =new int[max_len];

dst =new int[max_len];

initial_p =new int[4];

initial_m =new int[4];

// 垂直方向

        if (vert >0.0) {

vert = Math.abs(vert) +1.0;

std_dev = Math.sqrt(-(vert * vert) / (2 * Math.log(1.0 /255.0)));

// 初试化常量

            findConstants(n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev);

for (col =0; col < width; col++) {

for (k =0; k < max_len; k++) {

val_m[k] = val_p[k] =0;

}

for (t =0; t < height; t++) {

src[t] = psrc[t * row_stride + col];

}

sp_p_idx =0;

sp_m_idx = height -1;

vp_idx =0;

vm_idx = height -1;

initial_p[0] = src[0];

initial_m[0] = src[height -1];

for (row =0; row < height; row++) {

terms = (row <4) ? row :4;

for (i =0; i <= terms; i++) {

val_p[vp_idx] += n_p[i] * src[sp_p_idx - i] - d_p[i]

* val_p[vp_idx - i];

val_m[vm_idx] += n_m[i] * src[sp_m_idx + i] - d_m[i]

* val_m[vm_idx + i];

}

for (j = i; j <=4; j++) {

val_p[vp_idx] += (n_p[j] - bd_p[j]) * initial_p[0];

val_m[vm_idx] += (n_m[j] - bd_m[j]) * initial_m[0];

}

sp_p_idx++;

sp_m_idx--;

vp_idx++;

vm_idx--;

}

int i1, j1, k1, b;

int bend =1 * height;

double sum;

i1 = j1 = k1 =0;

for (b =0; b < bend; b++) {

sum = val_p[i1++] + val_m[j1++];

if (sum >255)

sum =255;

else if (sum <0)

sum =0;

dst[k1++] = (int) sum;

}

for (t =0; t < height; t++) {

psrc[t * row_stride + col] = dst[t];

}

}

}

// 水平方向

        if (horz >0.0) {

horz = Math.abs(horz) +1.0;

if (horz != vert) {

std_dev = Math.sqrt(-(horz * horz)

/ (2 * Math.log(1.0 /255.0)));

// 初试化常量

                findConstants(n_p, n_m, d_p, d_m, bd_p, bd_m, std_dev);

}

for (row =0; row < height; row++) {

for (k =0; k < max_len; k++) {

val_m[k] = val_p[k] =0;

}

for (t =0; t < width; t++) {

src[t] = psrc[row * row_stride + t];

}

sp_p_idx =0;

sp_m_idx = width -1;

vp_idx =0;

vm_idx = width -1;

initial_p[0] = src[0];

initial_m[0] = src[width -1];

for (col =0; col < width; col++) {

terms = (col <4) ? col :4;

for (i =0; i <= terms; i++) {

val_p[vp_idx] += n_p[i] * src[sp_p_idx - i] - d_p[i]

* val_p[vp_idx - i];

val_m[vm_idx] += n_m[i] * src[sp_m_idx + i] - d_m[i]

* val_m[vm_idx + i];

}

for (j = i; j <=4; j++) {

val_p[vp_idx] += (n_p[j] - bd_p[j]) * initial_p[0];

val_m[vm_idx] += (n_m[j] - bd_m[j]) * initial_m[0];

}

sp_p_idx++;

sp_m_idx--;

vp_idx++;

vm_idx--;

}

int i1, j1, k1, b;

int bend =1 * width;

double sum;

i1 = j1 = k1 =0;

for (b =0; b < bend; b++) {

sum = val_p[i1++] + val_m[j1++];

if (sum >255)

sum =255;

else if (sum <0)

sum =0;

dst[k1++] = (int) sum;

}

for (t =0; t < width; t++) {

psrc[row * row_stride + t] = dst[t];

}

}

}

return 0;

}

private void findConstants(double[] n_p,double[] n_m,double[] d_p,

double[] d_m,double[] bd_p,double[] bd_m,double std_dev) {

double div = Math.sqrt(2 *3.141593) * std_dev;

double x0 = -1.783 / std_dev;

double x1 = -1.723 / std_dev;

double x2 =0.6318 / std_dev;

double x3 =1.997 / std_dev;

double x4 =1.6803 / div;

double x5 =3.735 / div;

double x6 = -0.6803 / div;

double x7 = -0.2598 / div;

int i;

n_p[0] = x4 + x6;

n_p[1] = (Math.exp(x1)

* (x7 * Math.sin(x3) - (x6 +2 * x4) * Math.cos(x3)) + Math

.exp(x0) * (x5 * Math.sin(x2) - (2 * x6 + x4) * Math.cos(x2)));

n_p[2] = (2

                * Math.exp(x0 + x1)

* ((x4 + x6) * Math.cos(x3) * Math.cos(x2) - x5 * Math.cos(x3)

* Math.sin(x2) - x7 * Math.cos(x2) * Math.sin(x3)) + x6

* Math.exp(2 * x0) + x4 * Math.exp(2 * x1));

n_p[3] = (Math.exp(x1 +2 * x0)

* (x7 * Math.sin(x3) - x6 * Math.cos(x3)) + Math.exp(x0 +2

                * x1)

* (x5 * Math.sin(x2) - x4 * Math.cos(x2)));

n_p[4] =0.0;

d_p[0] =0.0;

d_p[1] = -2 * Math.exp(x1) * Math.cos(x3) -2 * Math.exp(x0)

* Math.cos(x2);

d_p[2] =4 * Math.cos(x3) * Math.cos(x2) * Math.exp(x0 + x1)

+ Math.exp(2 * x1) + Math.exp(2 * x0);

d_p[3] = -2 * Math.cos(x2) * Math.exp(x0 +2 * x1) -2 * Math.cos(x3)

* Math.exp(x1 +2 * x0);

d_p[4] = Math.exp(2 * x0 +2 * x1);

for (i =0; i <=4; i++) {

d_m[i] = d_p[i];

}

n_m[0] =0.0;

for (i =1; i <=4; i++) {

n_m[i] = n_p[i] - d_p[i] * n_p[0];

}

double sum_n_p, sum_n_m, sum_d;

double a, b;

sum_n_p =0.0;

sum_n_m =0.0;

sum_d =0.0;

for (i =0; i <=4; i++) {

sum_n_p += n_p[i];

sum_n_m += n_m[i];

sum_d += d_p[i];

}

a = sum_n_p / (1.0 + sum_d);

b = sum_n_m / (1.0 + sum_d);

for (i =0; i <=4; i++) {

bd_p[i] = d_p[i] * a;

bd_m[i] = d_m[i] * b;

}

}

/**

* 图片锐化(拉普拉斯变换)

*

    * @param mBitmapSrc 图片源

    * @return Bitmap

*/

    public Bitmap sharpenImageAmeliorate(Bitmap mBitmapSrc) {

// 拉普拉斯矩阵

        int[] laplacian =new int[]{-1, -1, -1, -1,9, -1, -1, -1, -1};

int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.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];

mBitmapSrc.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);

return bitmap;

}

/**

* 图片复古

*

    * @param mBitmapSrc 图片源

    * @return Bitmap

*/

    public Bitmap oldRemeberImage(Bitmap mBitmapSrc) {

/*

* 怀旧处理算法即设置新的RGB

* R=0.393r+0.769g+0.189b

* G=0.349r+0.686g+0.168b

* B=0.272r+0.534g+0.131b

*/

        int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.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];

mBitmapSrc.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;

}

/**

* 图片浮雕

* 将当前像素点的RGB值分别与255之差后的值作为当前点的RGB

* 灰度图像:通常使用的方法是gray=0.3*pixR+0.59*pixG+0.11*pixB

*

    * @param mBitmapSrc 图片源

    * @return Bitmap

*/

    public Bitmap reliefImage(Bitmap mBitmapSrc) {

/*

* 算法原理:(前一个像素点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 = mBitmapSrc.getWidth();

int height = mBitmapSrc.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];

mBitmapSrc.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 mBitmapSrc  图片源

    * @param position 光照位置 默认居中

    * @param strength    光照强度 100-150

    * @return Bitmap

*/

    public Bitmap sunshineImage(Bitmap mBitmapSrc, Position position,float strength) {

/*

* 算法原理:(前一个像素点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 = mBitmapSrc.getWidth();

int height = mBitmapSrc.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;

int centerY;

if (position == Position.LEFT_DOWN){centerX = width * (1/4); centerY = height * (3/4);}

else if (position == Position.LEFT_UP){centerX = width * (1/4); centerY = height * (1/4);}

else if (position == Position.RIGHT_DOWN){centerX = width * (3/4); centerY = height * (3/4);}

else if (position == Position.RIGHT_UP){centerX = width * (3/4); centerY = height * (1/4);}

else {centerX = width /2; centerY = height /2;}//默认居中

        int radius = Math.min(centerX, centerY);

int[] pixels =new int[width * height];

mBitmapSrc.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 mBitmapSrc 图片源

    * @return Bitmap

*/

    public Bitmap iceImage(Bitmap mBitmapSrc) {

int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.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];

mBitmapSrc.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 mBitmapSrc 图片源

    * @param w          压缩后的宽度 负数时为反向

    * @param h          压缩后的高度 负数为反向

    * @return Bitmap

*/

    public Bitmap zoomBitmap(Bitmap mBitmapSrc,int w,int h) {

int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.getHeight();

Matrix matrix =new Matrix();

float scaleWidth = ((float) w / width);

float scaleHeight = ((float) h / height);

matrix.postScale(scaleWidth, scaleHeight);

return Bitmap.createBitmap(mBitmapSrc,0,0, width, height, matrix,true);

}

/**

* 按比例放大缩小图片

*

    * @param mBitmapSrc  图片源

    * @param widthScale  宽缩放比

    * @param heightScale 高缩放比

    * @return Bitmap

*/

    public Bitmap zoomBitmap(Bitmap mBitmapSrc,float widthScale,float heightScale) {

Matrix matrix =new Matrix();

matrix.postScale(widthScale, heightScale);

return Bitmap.createBitmap(mBitmapSrc,0,0, mBitmapSrc.getWidth(), mBitmapSrc.getHeight(), matrix,true);

}

/**

* 将Drawable转化为Bitmap

*

    * @param mDrawableSrc 要转化的源drawable

    * @return Bitmap

*/

    public Bitmap drawableToBitmap(Drawable mDrawableSrc) {

int width = mDrawableSrc.getIntrinsicWidth();

int height = mDrawableSrc.getIntrinsicHeight();

Bitmap bitmap = Bitmap.createBitmap(width, height,

mDrawableSrc.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888

                        : Bitmap.Config.RGB_565);

Canvas canvas =new Canvas(bitmap);

mDrawableSrc.setBounds(0,0, width, height);

mDrawableSrc.draw(canvas);

return bitmap;

}

/**

* 倒影图片

*

    * @param mBitmapSrc 图片源

    * @return Bitmap

*/

    public Bitmap toReflectedImage(Bitmap mBitmapSrc) {

final int reflectionGap =4;

int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.getHeight();

Matrix matrix =new Matrix();

matrix.preScale(1, -1);

Bitmap reflectionImage = Bitmap.createBitmap(mBitmapSrc,0,

height /2, width, height /2, matrix,false);

Bitmap bitmap = Bitmap.createBitmap(width,

(height + height /2), Bitmap.Config.ARGB_8888);

Canvas canvas =new Canvas(bitmap);

canvas.drawBitmap(mBitmapSrc,0,0,null);

Paint defaultPaint =new Paint();

canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint);

canvas.drawBitmap(reflectionImage,0, height + reflectionGap,null);

Paint paint =new Paint();

LinearGradient shader =new LinearGradient(0,

mBitmapSrc.getHeight(),0, bitmap.getHeight()

+ reflectionGap,0x70FFFFFF,0x00FFFFFF,

Shader.TileMode.MIRROR);

paint.setShader(shader);

paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));

canvas.drawRect(0, height, width, bitmap.getHeight()

+ reflectionGap, paint);

return bitmap;

}

/**

* 水印特效

*

    * @param mBitmapSrc  图片源

    * @param waterMarkSrc Bitmap

    * @param position position

    * @return Bitmap

*/

    public Bitmap createBitmapWithWatermark(Bitmap mBitmapSrc, Bitmap waterMarkSrc, Position position) {

if (mBitmapSrc ==null) {

return null;

}

int w = mBitmapSrc.getWidth();

int h = mBitmapSrc.getHeight();

int ww = waterMarkSrc.getWidth();

int wh = waterMarkSrc.getHeight();

Bitmap newBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);// 创建一个新的和SRC长度宽度一样的位图

        Canvas cv =new Canvas(newBitmap);

cv.drawBitmap(mBitmapSrc,0,0,null);// 在 0,0坐标开始画入src

        if (position == Position.RIGHT_DOWN)

cv.drawBitmap(waterMarkSrc, w - ww +5, h - wh +5,null);// 在src的右下角画入水印

        else if (position == Position.RIGHT_UP)

cv.drawBitmap(waterMarkSrc, w - ww +5,5,null);// 在src的右上角画入水印

        else if (position == Position.LEFT_DOWN)

cv.drawBitmap(waterMarkSrc,5, h - wh +5,null);// 在src的左下角画入水印

        else if (position == Position.LEFT_UP)

cv.drawBitmap(waterMarkSrc,5,5,null);// 在src的左上角画入水印

        else

            cv.drawBitmap(waterMarkSrc, w/2 - ww/2, h/2 - wh,null);// 在src的中间画入水印

        cv.save(Canvas.ALL_SAVE_FLAG);// 保存

        cv.restore();// 存储

        return newBitmap;

}

/**

* 获取缩略图

* 默认获取的宽高为 100

*

    * @param mBitmapSrc 图片源

    * @param width      int

    * @param height    int

    * @return Bitmap

*/

    public Bitmap getThumbBitmap(Bitmap mBitmapSrc,int width,int height) {

if (width ==0) width =100;

if (height ==0) height =100;

Bitmap thumbBitmap;

thumbBitmap = ThumbnailUtils.extractThumbnail(mBitmapSrc, width, height);

return thumbBitmap;

}

/**

* 黑白照片

*

    * @param mBitmapSrc 图片源

    * @return Bitmap

*/

public Bitmap toBlackAndWhite(Bitmap mBitmapSrc) {

int mBitmapWidth;

int mBitmapHeight;

mBitmapWidth = mBitmapSrc.getWidth();

mBitmapHeight = mBitmapSrc.getHeight();

Bitmap bitmap = Bitmap.createBitmap(mBitmapWidth, mBitmapHeight,

Bitmap.Config.ARGB_8888);

int iPixel;

for (int i =0; i < mBitmapWidth; i++) {

for (int j =0; j < mBitmapHeight; j++) {

int curr_color = mBitmapSrc.getPixel(i, j);

int avg = (Color.red(curr_color) + Color.green(curr_color) + Color

.blue(curr_color)) /3;

if (avg >=100) {

iPixel =255;

}else {

iPixel =0;

}

int modify_color = Color.argb(255, iPixel, iPixel, iPixel);

bitmap.setPixel(i, j, modify_color);

}

}

return bitmap;

}

//二值

    public Bitmap convertBlackWhite(Bitmap bmp) {

int width = bmp.getWidth();

int height = bmp.getHeight();

int[] pixels =new int[width * height];

bmp.getPixels(pixels,0, width,0,0, width, height);

int alpha =0xFF <<24;

for (int i =0; i < height; i++) {

for (int j =0; j < width; j++) {

int grey = pixels[width * i + j];

// 分离三原色

                int red = ((grey &0x00FF0000) >>16);

int green = ((grey &0x0000FF00) >>8);

int blue = (grey &0x000000FF);

//                // 转化成灰度像素

//                grey = (int) (red * 0.3 + green * 0.59 + blue * 0.11);

//先求最大值

                int max = Math.max(Math.max(red, green), blue);

//                //某个颜色值作为分界

                if (red == green && red == blue) {

grey = red;

}else if(max >200){

grey =255;

}else {

grey =0;

}

grey = alpha | (grey <<16) | (grey <<8) | grey;

pixels[width * i + j] = grey;

}

}

// 新建图片

        Bitmap newbmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);

newbmp.setPixels(pixels,0, width,0,0, width, height);

saveBitmap2File(newbmp,"bit", Environment.getExternalStorageDirectory().getPath() +"/data", Format.PNG);

return ThumbnailUtils.extractThumbnail(newbmp, width, height);

}

/**

* 底片效果

*

    * @param mBitmapSrc 图片源

    * @return Bitmap

*/

    public Bitmap negativeFilm(Bitmap mBitmapSrc) {

// RGBA的最大值

        final int MAX_VALUE =255;

int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.getHeight();

Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);

int pixR;

int pixG;

int pixB;

int pixColor;

int newR;

int newG;

int newB;

int[] pixels =new int[width * height];

mBitmapSrc.getPixels(pixels,0, width,0,0, width, height);

int pos =0;

for (int i =1, length = height -1; i < length; i++) {

for (int k =1, len = width -1; k < len; k++) {

pos = i * width + k;

pixColor = pixels[pos];

pixR = Color.red(pixColor);

pixG = Color.green(pixColor);

pixB = Color.blue(pixColor);

newR = MAX_VALUE - pixR;

newG = MAX_VALUE - pixG;

newB = MAX_VALUE - pixB;

newR = Math.min(MAX_VALUE, Math.max(0, newR));

newG = Math.min(MAX_VALUE, Math.max(0, newG));

newB = Math.min(MAX_VALUE, Math.max(0, newB));

pixels[pos] = Color.argb(MAX_VALUE, newR, newG, newB);

}

}

bitmap.setPixels(pixels,0, width,0,0, width, height);

return bitmap;

}

/**

* 油画效果

*

    * @param mBitmapSrc 图片源

    * @return Bitmap

*/

    public Bitmap oilPainting(Bitmap mBitmapSrc) {

Bitmap bmpReturn = Bitmap.createBitmap(mBitmapSrc.getWidth(),

mBitmapSrc.getHeight(), Bitmap.Config.RGB_565);

int color =0;

int Radio =0;

int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.getHeight();

Random rnd =new Random();

int iModel =10;

int i = width - iModel;

while (i >1) {

int j = height - iModel;

while (j >1) {

int iPos = rnd.nextInt(100000) % iModel;

color = mBitmapSrc.getPixel(i + iPos, j + iPos);

bmpReturn.setPixel(i, j, color);

j = j -1;

}

i = i -1;

}

return bmpReturn;

}

/**

* 图片合成

*

    * @param position  组合位置: -1 :左  1 :右  2 :上  -2 :下

    * @param mBitmapSrcs 图片源

    * @return Bitmap

*/

    public Bitmap photoMix(Position position, Bitmap... mBitmapSrcs) {

if (mBitmapSrcs.length <=0) {

return null;

}

if (mBitmapSrcs.length ==1) {

return mBitmapSrcs[0];

}

Bitmap newBitmap = mBitmapSrcs[0];

for (int i =1; i < mBitmapSrcs.length; i++) {

newBitmap = createBitmapForPhotoMix(newBitmap, mBitmapSrcs[i], position);

}

return newBitmap;

}

private Bitmap createBitmapForPhotoMix(Bitmap first, Bitmap second, Position position) {

if (first ==null) {

return null;

}

if (second ==null) {

return first;

}

int fw = first.getWidth();

int fh = first.getHeight();

int sw = second.getWidth();

int sh = second.getHeight();

Bitmap newBitmap =null;

if (position == Position.LEFT) {

newBitmap = Bitmap.createBitmap(fw + sw, fh > sh ? fh : sh, Bitmap.Config.ARGB_8888);

Canvas canvas =new Canvas(newBitmap);

canvas.drawBitmap(first, sw,0,null);

canvas.drawBitmap(second,0,0,null);

}else if (position == Position.RIGHT) {

newBitmap = Bitmap.createBitmap(fw + sw, fh > sh ? fh : sh, Bitmap.Config.ARGB_8888);

Canvas canvas =new Canvas(newBitmap);

canvas.drawBitmap(first,0,0,null);

canvas.drawBitmap(second, fw,0,null);

}else if (position == Position.TOP) {

newBitmap = Bitmap.createBitmap(sw > fw ? sw : fw, fh + sh, Bitmap.Config.ARGB_8888);

Canvas canvas =new Canvas(newBitmap);

canvas.drawBitmap(first,0, sh,null);

canvas.drawBitmap(second,0,0,null);

}else if (position ==  Position.BOTTOM) {

newBitmap = Bitmap.createBitmap(sw > fw ? sw : fw, fh + sh, Bitmap.Config.ARGB_8888);

Canvas canvas =new Canvas(newBitmap);

canvas.drawBitmap(first,0,0,null);

canvas.drawBitmap(second,0, fh,null);

}else if (position ==  Position.CENTRE) {

newBitmap = Bitmap.createBitmap(Math.max(fw, sw), Math.max(fw, sw), Bitmap.Config.ARGB_8888);

Canvas canvas =new Canvas(newBitmap);

canvas.drawBitmap(first,0,0,null);

canvas.drawBitmap(second, fw /2, fh /2,null);

}

return newBitmap;

}

/**

* bitmap 位图保存成文件

*

    * @param mBitmapSrc 图片源

    * @param fileName  文件名

    * @param filePath  保存的文件路径(默认为空时在内存根目录)

    * @param format    保存的图片格式(默认 JPEG)

*/

    public void saveBitmap2File(Bitmap mBitmapSrc, String fileName, String filePath, Format format) {

String suffix ="jpg";

if (TextUtils.isEmpty(filePath))

filePath = Environment.getExternalStorageDirectory().getAbsolutePath().toString();

Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.JPEG;

if (format == Format.JPEG){

compressFormat = Bitmap.CompressFormat.JPEG;

suffix =".jpeg";

}

else if (format == Format.PNG){

compressFormat = Bitmap.CompressFormat.PNG;

suffix =".png";

}

else if (format == Format.WEBP){

compressFormat = Bitmap.CompressFormat.WEBP;

suffix =".webp";

}

File file =new File(filePath + File.separator, fileName + suffix);

try {

file.createNewFile();

OutputStream os =new FileOutputStream(file);

mBitmapSrc.compress(compressFormat,100, os);

os.flush();

}catch (IOException e) {

e.printStackTrace();

}

}

/**

* 图片平滑处理

* 3*3掩模处理(平均处理),降低噪声

*

    * @param mBitmapSrc 图片源

    * @return Bitmap

*/

    public Bitmap smoothImage(Bitmap mBitmapSrc) {

int w = mBitmapSrc.getWidth();

int h = mBitmapSrc.getHeight();

int[] data =new int[w * h];

mBitmapSrc.getPixels(data,0, w,0,0, w, h);

int[] resultData =new int[w * h];

try {

resultData = filter(data, w, h);

}catch (Exception e) {

e.printStackTrace();

}

Bitmap newBitmap = Bitmap.createBitmap(resultData, w, h, Bitmap.Config.ARGB_8888);

return newBitmap;

}

private int[] filter(int[] data,int width,int height)throws Exception {

int filterData[] =new int[data.length];

int min =10000;

int max = -10000;

if (data.length != width * height)return filterData;

try {

for (int i =0; i < height; i++) {

for (int j =0; j < width; j++) {

if (i ==0 || i ==1 || i == height -1 || i == height -2 || j ==0 || j ==1 || j == width -1 || j == width -2) {

filterData[i * width + j] = data[i * width + j];

}else {

double average;//中心的九个像素点

                        average = (data[i * width + j] + data[i * width + j -1] + data[i * width + j +1]

+ data[(i -1) * width + j] + data[(i -1) * width + j -1] + data[(i -1) * width + j +1]

+ data[(i +1) * width + j] + data[(i +1) * width + j -1] + data[(i +1) * width + j +1]) /9;

filterData[i * width + j] = (int) (average);

}

if (filterData[i * width + j] < min)

min = filterData[i * width + j];

if (filterData[i * width + j] > max)

max = filterData[i * width + j];

}

}

for (int i =0; i < width * height; i++) {

filterData[i] = (filterData[i] - min) *255 / (max - min);

}

}catch (Exception e) {

e.printStackTrace();

throw new Exception(e);

}

return filterData;

}

/**

* 图片增亮

*

    * @param mBitmapSrc    图片源

    * @param brightenOffset 增加的亮度值

    * @return Bitmap

*/

    public Bitmap brightenBitmap(Bitmap mBitmapSrc,int brightenOffset) {

int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.getHeight();

int[] pix =new int[width * height];

mBitmapSrc.getPixels(pix,0, width,0,0, width, height);

// Apply pixel-by-pixel change

        int index =0;

for (int y =0; y < height; y++) {

for (int x =0; x < width; x++) {

int r = (pix[index] >>16) &0xff;

int g = (pix[index] >>8) &0xff;

int b = pix[index] &0xff;

r = Math.max(0, Math.min(255, r + brightenOffset));

g = Math.max(0, Math.min(255, g + brightenOffset));

b = Math.max(0, Math.min(255, b + brightenOffset));

pix[index] =0xff000000 | (r <<16) | (g <<8) | b;

index++;

}// x

        }// y

// Change bitmap to use new array

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);

bitmap.setPixels(pix,0, width,0,0, width, height);

mBitmapSrc =null;

pix =null;

return bitmap;

}

/**

* 均值滤波

*

    * @param mBitmapSrc  图片源

    * @param filterWidth  滤波宽度值

    * @param filterHeight 滤波高度值

*/

    public Bitmap averageFilter(Bitmap mBitmapSrc,int filterWidth,int filterHeight) {

int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.getHeight();

int[] pixNew =new int[width * height];

int[] pixOld =new int[width * height];

mBitmapSrc.getPixels(pixNew,0, width,0,0, width, height);

mBitmapSrc.getPixels(pixOld,0, width,0,0, width, height);

// Apply pixel-by-pixel change

        int filterHalfWidth = filterWidth /2;

int filterHalfHeight = filterHeight /2;

int filterArea = filterWidth * filterHeight;

for (int y = filterHalfHeight; y < height - filterHalfHeight; y++) {

for (int x = filterHalfWidth; x < width - filterHalfWidth; x++) {

// Accumulate values in neighborhood

                int accumR =0, accumG =0, accumB =0;

for (int dy = -filterHalfHeight; dy <= filterHalfHeight; dy++) {

for (int dx = -filterHalfWidth; dx <= filterHalfWidth; dx++) {

int index = (y + dy) * width + (x + dx);

accumR += (pixOld[index] >>16) &0xff;

accumG += (pixOld[index] >>8) &0xff;

accumB += pixOld[index] &0xff;

}// dx

                }// dy

// Normalize

                accumR /= filterArea;

accumG /= filterArea;

accumB /= filterArea;

int index = y * width + x;

pixNew[index] =0xff000000 | (accumR <<16) | (accumG <<8) | accumB;

}// x

        }// y

// Change bitmap to use new array

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);

bitmap.setPixels(pixNew,0, width,0,0, width, height);

mBitmapSrc =null;

pixOld =null;

pixNew =null;

return bitmap;

}

/**

* 中值滤波

*

    * @param mBitmapSrc  图片源

    * @param filterWidth  滤波宽度值

    * @param filterHeight 滤波高度值

*/

    public Bitmap medianFilter(Bitmap mBitmapSrc,int filterWidth,int filterHeight) {

int width = mBitmapSrc.getWidth();

int height = mBitmapSrc.getHeight();

int[] pixNew =new int[width * height];

int[] pixOld =new int[width * height];

mBitmapSrc.getPixels(pixNew,0, width,0,0, width, height);

mBitmapSrc.getPixels(pixOld,0, width,0,0, width, height);

// Apply pixel-by-pixel change

        int filterHalfWidth = filterWidth /2;

int filterHalfHeight = filterHeight /2;

int filterArea = filterWidth * filterHeight;

for (int y = filterHalfHeight; y < height - filterHalfHeight; y++) {

for (int x = filterHalfWidth; x < width - filterHalfWidth; x++) {

// Accumulate values in neighborhood

                int accumR =0, accumG =0, accumB =0;

for (int dy = -filterHalfHeight; dy <= filterHalfHeight; dy++) {

for (int dx = -filterHalfWidth; dx <= filterHalfWidth; dx++) {

int index = (y + dy) * width + (x + dx);

accumR += (pixOld[index] >>16) &0xff;

accumG += (pixOld[index] >>8) &0xff;

accumB += pixOld[index] &0xff;

}// dx

                }// dy

// Normalize

                accumR /= filterArea;

accumG /= filterArea;

accumB /= filterArea;

int index = y * width + x;

pixNew[index] =0xff000000 | (accumR <<16) | (accumG <<8) | accumB;

}// x

        }// y

// Change bitmap to use new array

        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);

bitmap.setPixels(pixNew,0, width,0,0, width, height);

mBitmapSrc =null;

pixOld =null;

pixNew =null;

return bitmap;

}

}

相关文章

  • 一些常用的图像处理方法

    public class ImageProcessHelper { ///////////////////////...

  • 数字图像处理的基本原理和常用方法

    数字图像处理的基本原理和常用方法 数字图像处理是指将图像信号转换成数字信号并利用计算机对其进行处理的过程。图像处理...

  • 图像预处理的常用方法

    Gamma校正 参考博客

  • 图像的卷积

    1.卷积的定义图像卷积是对图像进行处理的最常用方法,如:去噪、滤波、边缘提取等。对图像做卷积操作其实就是利用卷积核...

  • 图像金字塔

    图像金字塔是图像处理和计算机视觉中常用到的概念,常常用于多尺度处理领域(multiscale processing...

  • iOS 图片处理的常用方法

    最近整理了图片常用处理的一些方法,包括 方法实现:

  • PS图处的小技巧

    1.photoshop图象处理中的一些小技巧 Photoshop是印前系统中最常用也是最实用的专业图像处理软件,经...

  • 图像处理库 pillow应用-验证码去噪

    前面我们学习了 Python 的图像处理库 PIL,学会了一些相关的图像处理方法,好多人心里会问:有什么用呢?这一...

  • pyspark DCT(离散余弦变换)

    DCT:将时域的N维实数序列转换成频域的N维实数序列常用于信号处理和图像处理,对信号和图像(包括静止图像和运动图像...

  • ios图像处理的一些方法

    图像处理是软件开发中很重要的一门技术,像ps,各种美颜app,主要就是运用到它。 在apple相关开发领域,图像处...

网友评论

      本文标题:一些常用的图像处理方法

      本文链接:https://www.haomeiwen.com/subject/qvrtoxtx.html