首页 / 资讯中心 / 文章详情

Java图像处理:使用缓冲区加快图形显示以及更多图像算法实现

Java图像处理:使用缓冲区加快图形显示以及更多图像算法实现 ★ FEATURED ARTICLE
Java图像处理使用缓冲区加快图形显示并实现更多图像算法前言在上一篇中我们实现了图像处理的基础读取像素、绘制图片、灰度、马赛克效果。本篇在它的基础上更新① 用缓冲区提高绘制速度② 扩展更多图像算法。环境JDK 17IntelliJ IDEA纯 Java 项目未使用 Maven一、整体设计仍然是两个类DrawPixel界面——顶部工具栏放按钮中间放画布拿画笔、绑定监听器PixelListener事件处理——继承MouseAdapter鼠标并实现ActionListener按钮。二、界面用数组 循环批量造按钮效果多了以后一个个写JButton太啰嗦。用一个数组装所有效果名循环添加按钮String[]effects{原图,灰度,马赛克,底片,浮雕,图片融合,变暗,亮度增强,复古,镜像,锐化,二值化,通道交换};PixelListenerlistenernewPixelListener();for(Stringname:effects){//for-each结构遍历数组每个元素JButtonbuttonnewJButton(name);northPanel.add(button);button.addActionListener(listener);//这里并不需要给每个效果使用不同的按钮组件变量}按钮文字由效果名决定点按钮时actionPerformed里effect e.getActionCommand();就能自动知道点了哪个因此不需要给每个按钮单独写不同的变量名称。三、加载图片getImagePixelBufferedImagebufferedImageImageIO.read(file);//读取为 BufferedImageintwbufferedImage.getWidth();inthbufferedImage.getHeight();int[][]pixelArrnewint[h][w];//用二维数组存像素for(inti0;ih;i)for(intj0;jw;j)pixelArr[i][j]bufferedImage.getRGB(j,i);//取像素注意 (j,i)四、绘制用缓冲区提速4.1 为什么慢在上一篇中我们每取一个像素点都会调用一次g.drawLine几十万~上百万次而这部分代码的实际执行过程需要将数据先传输到jvm中经过处理在传递出来并绘制到我们可以看到的窗口上这种重复的信息传递会消耗大量时间因此在本篇中我们对此做出优化现将所有像素点传入并在jvm的缓冲区内画出缓冲图形再一次性将缓冲图形的信息传出并绘制到屏幕上。4.2 思路攒到内存再一次性贴出来使用**BufferedImage内存里的一张看不见的图**先把像素画在这张缓冲图片上最后drawImage一次性画到画布上。drawPixel外层循环缓冲区最后贴画布draw处理单个像素按effect分发画到缓冲区上。publicvoiddrawPixel(int[][]pixelArr){hpixelArr.length;wpixelArr[0].length;BufferedImagebuffernewBufferedImage(w,h,BufferedImage.TYPE_INT_RGB);//再缓冲内创建缓冲图片Graphicsgbbuffer.getGraphics();//获取缓冲图片的画笔for(inti0;ih;i)for(intj0;jw;j)draw(pixelArr,i,j,gb);//将像素点先画到缓冲上g.drawImage(buffer,0,0,null);//最后一次性将缓冲图片的内容会知道画布上draweffecteffect;//更新效果}注意使用了两支不同的画笔gb是取自缓冲图片的、g是画布的4.3 draw处理单个像素publicvoiddraw(int[][]pixelArr,inti,intj,Graphicsgb){intrgb;if(effect.equals(镜像))rgbpixelArr[i][w-1-j];//镜像算法特殊需要再开始判断取对称位置elsergbpixelArr[i][j];intredrgb160xFF;intgreenrgb80xFF;intbluergb0xFF;//按effect处理 red/green/blue ...对于各种效果进行分类讨论gb.setColor(newColor(red,green,blue));gb.drawLine(j,i,j,i);//画到缓冲上}五、图像算法图像处理逻辑都写在draw里按effect分。后续如果新加效果只需要更改这一个方法即可。下面简单展示一些图像处理效果的公式代码省略不再一一展示。效果处理r,g,b均为0~255灰度gray(rgb)/3; rgbgray底片r255-r; g255-g; b255-b亮度增强r50夹到 255变暗r-50夹到 0复古(sepia)nR0.393r0.769g0.189b等浮雕r r - 左上邻居r 128锐化r 5r - 上 - 下 - 左 - 右马赛克取pixelArr[i/10*10][j/10*10]每块同色镜像rgb pixelArr[i][w-1-j]图片融合两张图取平均(图A 图B)/2六、架构图片只读一次效果变了才重画哪怕使用了缓冲区逐像素处理的任务依然很重因此保留架构图片只读取一次存进字段pixelArr用effect选中和draweffect已画比较只有不一样才重画。if(pixelArrnull)pixelArrgetImagePixel(newFile(图片路径));if(!effect.equals(draweffect))drawPixel(pixelArr);七、错误记录缓冲画笔取多次buffer.getGraphics()要只取一次必须写在循环外部否则每像素取一次会创建海量对象所以画笔只能通过传参数的方式传递给方法内部。八、总结本篇用缓冲区对逐点绘制进行了效率优化并扩展了十余种图像算法灰度/底片/亮度/变暗/复古/浮雕/锐化/马赛克/镜像/图片融合。核心图像一堆像素值改像素值就能改效果同时靠缓冲区来高效的绘制图形。
阅读完成 · 觉得有帮助?
咨询建站