java 针对不规则形状图形进行描边操作

发布时间:2023-10-03作者:laosun阅读(1334)

java

java 针对不规则形状图形进行描边操作,检测图形边缘,边缘检测

    看效果图:

    1696315287366064376.png    1696315287340032104.png                                    


    源码代码:

    /**
                         .::::.
                       .::::::::.
                      :::::::::::    佛主保佑、永无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;
        }
    
    }


3 +1

版权声明

 Java  源码

 请文明留言

0 条评论