发布时间:2023-10-03作者:laosun阅读(1334)
java 针对不规则形状图形进行描边操作,检测图形边缘,边缘检测
看效果图:
源码代码:
/** .::::. .::::::::. ::::::::::: 佛主保佑、永无Bug ..:::::::::::' '::::::::::::' .:::::::::: '::::::::::::::.. ..::::::::::::. ``:::::::::::::::: ::::``:::::::::' .:::. ::::' ':::::' .::::::::. .::::' :::: .:::::::'::::. .:::' ::::: .:::::::::' ':::::. .::' :::::.:::::::::' ':::::. .::' ::::::::::::::' ``::::. ...::: ::::::::::::' ``::. ```` ':. ':::::::::' ::::.. '.:::::' ':'````.. */ import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.TimeInterval; import lombok.extern.slf4j.Slf4j; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; /** * 描边 * * @author sun */ @Slf4j public class DetectEdges { public static void main(String[] args) throws IOException { // 读取图像(假设图像背景是透明的,非规则形状是不透明的) // BufferedImage image = ImageIO.read(new File("/Users/sun/Documents/test/QQ.png")); // BufferedImage image = ImageIO.read(new File("/Users/sun/Documents/test/pin.png")); // BufferedImage image = ImageIO.read(new File("/Users/sun/Documents/test/kafei.png")); // BufferedImage image = ImageIO.read(new File("/Users/sun/Documents/test/qiu.png")); BufferedImage image = ImageIO.read(new File("/Users/sun/Documents/test/A.png")); TimeInterval timer = DateUtil.timer(); // 描边操作 BufferedImage edgeDetectedImage = detectEdges(image, "#FF0000"); System.out.println("共耗时:" + timer.interval()); // 保存结果 ImageIO.write(edgeDetectedImage, "png", new File("/Users/sun/Documents/test/A2.png")); } /** * 不规则图形描边操作 * * @author sun * @param image 图片BufferedImage * @param hexCode 边框的颜色(十六进制代码,例如:#FF0000) * @return java.awt.image.BufferedImage 返回新的BufferedImage */ public static BufferedImage detectEdges(BufferedImage image, String hexCode) { BufferedImage edgeDetectedImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB); int height = image.getHeight(); int width = image.getWidth(); // 边框的颜色 Integer edgeColor = Color.decode(hexCode).getRGB(); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { // 获取当前像素的透明度 // log.info("开始获取xy:{},{}", x, y); int alpha = (image.getRGB(x, y) >> 24) & 0xFF; if (alpha < 1) { // 排除掉透明区域 continue; } // 判断当前坐标点是否是图片的边缘 boolean isEdgePixel = (x == 0 || x == image.getWidth() - 1 || y == 0 || y == image.getHeight() - 1); if (isEdgePixel) { // 当前坐标位于边上 edgeDetectedImage.setRGB(x, y, edgeColor); continue; } // 获取到相邻点 // 含四个斜对角相邻点 // int[][] adjacentPoints = new int[][]{{x, y - 1}, // 上 // {x, y + 1}, // 下 // {x - 1, y}, // 左 // {x + 1, y}, // 右 // {x - 1, y - 1}, // 左上 // {x - 1, y + 1}, // 左下 // {x + 1, y - 1}, // 右上 // {x + 1, y + 1} // 右下 // }; int[][] adjacentPoints = new int[][]{{x, y - 1}, // 上 {x, y + 1}, // 下 {x - 1, y}, // 左 {x + 1, y} // 右 }; for (int[] ap : adjacentPoints) { int neighborAlpha = (image.getRGB(ap[0], ap[1]) >> 24) & 0xFF; // int neighborAlpha = new Color(image.getRGB(x, y)).getAlpha(); if (neighborAlpha < 1) { // 有透明像素点,表示是边,并且跳出本次循环 edgeDetectedImage.setRGB(x, y, edgeColor); break; } } } } return edgeDetectedImage; } }
版权属于: 技术客
原文地址: https://www.sunjs.com/article/detail/be3ccdc375a0483995d183443dc4b29d.html
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。