Android 开源数字图像处理

发布于 2025-02-21 12:59:54 字数 10436 浏览 10 评论 0

类似于美图秀秀等软件,设计数学,数字图像处理

数字图像处理软件(一)

本人大三学生一枚,自学安卓有三四个月了,去公司实习两个月了,在工作上欠缺一些东西,所以决定开始写博客与各位大牛分享交流学习,写的不好勿喷~

写的不好的地方,请指出,虚心学习。

废话不多说,开始~

模块分为:

图片特效,人脸识别,图像调节,二维码,绘图器,图像相框

1.效果图:

至于布局文件什么的,就不多谈了。

(1)。图片特效:

下一篇讲讲解实现原理

数字图像处理软件(二)

这是数字图像处理软件系列的第二篇。

首先来讲解图像特效部分

1、选择本地图片,如下图结果:

底部状态栏有多种特效可以选择,有:怀旧,锐化,火焰,浮雕,柔化,光晕,红外,淡化,灰度等效果

下面我选择两种特效做讲解:

Duang~

效果图如下:

下面来讲解思路:

long start = System.currentTimeMillis();  
        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;  

//没张图片都可以转化为 RGB 信息,也就是说对 RGB 信息修改,意味着对图片的修改,也就是产生的一般特效(特殊的特效更为复杂)。

以下内容为核心处理:

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

//对每个像素点取 RGB,并修改,修改后替换原来信息。

 bitmap.setPixels(pixels, 0, width, 0, 0, width, height);  
        long end = System.currentTimeMillis();  
        Log.d("may", "used time="+(end - start));  
        return bitmap;  

//最后实现,返回位图。

数字图像处理(三)特效----锐化

关于锐化效果,感觉效果并没有达到预期的效果。

处理后感觉像素变的粗糙了。

这涉及到数学知识,是关于拉普拉斯矩阵的应用,而本人在数学方面并不牛,所以不敢在这细讲,怕误导大家。

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

//同样,和上一篇一样,对像素点的 RGB 做处理

不过这里要用上拉普拉斯矩阵,做信息修改。

以下是对像素的详细操作核心:

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;  

这样,锐化效果就达到了,虽然效果并不明显,本人还在优化当中。

数字图像处理软件-图片特效--浮雕效果(四)

接上之前的数字图像处理软件系列,其实这个 APP 很早之前就做完了,主要是模仿了美图秀秀。之前因为太多事而耽误了,现在继续把这系列的博客写完

那么开始正文:

这次要讲的图片特效部分是:浮雕特效

老规矩,话不多说,我们来看效果图:

那么下面就开始讲解:

浮雕的特性我们必须得知道,浮雕不凸显细节但是凸显轮廓,这是浮雕的特性,那么轮廓有哪些特点呢?我个人认为,图片中的事物,他们的轮廓区分,基本可以靠颜色区分,也就是边界的颜色差异,当然这个方法只是可以突出局部的轮廓,但这也足够用了。所以和前几篇一样,我们需要用RGB操作,即比较RGB(凸显边界)

 //浮雕  
    public static Bitmap  img_fudiao(Bitmap  bm){  

 intwidth = bm.getWidth();      
int height = bm.getHeight();  
 Bitmap  bmp= Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);   

 int color,color2;    
     //前一个像素    
    int pixelsR,pixelsR2;    
    int pixelsG,pixelsG2;    
    int pixelsB,pixelsB2;    
     //当前像素    
      
   
   
int[] pixels = new int[width * height];  
bm.getPixels(pixels, 0, width, 0, 0, width, height);  
   
for(int i=1;i<width*height;i++)  
{  
  color = pixels[i-1];    
               //前一个像素    
               pixelsR = Color.red(color);    
               pixelsG = Color.green(color);    
               pixelsB = Color.blue(color);    
               //当前像素    
               color2 = pixels[i];    
               pixelsR2 = Color.red(color2);    
               pixelsG2 = Color.green(color2);    
               pixelsB2 = Color.blue(color2);    
                   
               pixelsR = (pixelsR - pixelsR2 + 127);    
               pixelsG = (pixelsG - pixelsG2 + 127);    
               pixelsB = (pixelsB - pixelsB2 + 127);    
               //均小于等于 255    
               if(pixelsR > 255){    
                   pixelsR = 255;    
               }    
                   
               if(pixelsG > 255){    
                   pixelsG = 255;    
               }    
                   
               if(pixelsB > 255){    
                   pixelsB = 255;    
               }    
               pixels[i] = Color.argb(255, pixelsR, pixelsG, pixelsB);  
}   
   
bmp.setPixels(pixels, 0, width, 0, 0, width, height);  
     
   return bmp;  
    }  

在代码中可以看到,每次去相邻两项的RGB,让他们做比较,差异色大的可以基本确定是边界色,也就可以凸显轮廓

最后返回结果。

数字图像处理软件-特效--光晕特效(五)

光晕特效在于凸显一个光圈:

下面是效果图

 /**   
     * 光晕效果   
     * @param bmp   
     * @param x 光晕中心点在 bmp 中的 x 坐标   
     * @param y 光晕中心点在 bmp 中的 y 坐标   
     * @param r 光晕的半径   
     * @return   
     */    
    public static Bitmap halo(Bitmap bmp, int x, int y, float r)    
    {    
        long start = System.currentTimeMillis();    
        // 高斯矩阵    
        int[] gauss = new int[] { 1, 2, 1, 2, 4, 2, 1, 2, 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 delta = 18; // 值越小图片会越亮,越大则越暗    
            
        int idx = 0;    
        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;    
                int distance = (int) (Math.pow(k - x, 2) + Math.pow(i - y, 2));    
                // 不是中心区域的点做模糊处理    
                if (distance > r * r)    
                {    
                    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 + (int) (pixR * gauss[idx]);    
                            newG = newG + (int) (pixG * gauss[idx]);    
                            newB = newB + (int) (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;    
                }    
            }    
        }    
            
        bitmap.setPixels(pixels, 0, width, 0, 0, width, height);    
        long end = System.currentTimeMillis();    
        Log.d("may", "used time="+(end - start));    
        return bitmap;    
    }  

如上所说我们需要对圆做设置:1.圆心的 XY。2.圆的半径。

有了这些设定,我们就可以确定圆圈的范围,对园内和圆外做不同的操作,这里我让圆内保持不变,圆外改变,这样就完成了,当然大家可以针对园内做成亮色,把离圆心近的地方做更深程度的亮色,这样就有光线的感觉了。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

千紇

暂无简介

文章
评论
29 人气
更多

推荐作者

身边

文章 0 评论 0

qq_oxT0yE

文章 0 评论 0

卷着的草席

文章 0 评论 0

£冰雨忧蓝°

文章 0 评论 0

我还不会笑

文章 0 评论 0

Unbroken

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文