图片抠图和换色

好久没记录了,今天找抠图接口实在找的烦,市面上的免费抠图api不好用,收费的又太贵了,甚至还有的给你加水印,要求去水印也要收费一次。
无奈,还是自己写工具类吧。
废话不多说,还是贴代码,好用点个赞

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**

  • Author: zzq

  • Time: 2024/12/30 10:32:11
    */
    public class AutoImageRemoval {
    public static void main(String[] args) {

         koutu("C:\\Users\\Administrator\\Pictures\\图片7.png",
                 "C:\\Users\\Administrator\\Pictures\\图片71.png");
         // 将前景替换为红色
     replaceForegroundWithColor("C:\\Users\\Administrator\\Pictures\\图片71.png",
             "C:\\Users\\Administrator\\Pictures\\图片711.png",
             "#FFFFFF"); // 红色
    

    }

    public static String koutu(String inputPath, String outputPath){
    try {
    // 加载图片
    BufferedImage image = ImageIO.read(new File(inputPath));

         // 自动检测背景色
         int backgroundColor = detectBackgroundColor(image);
    
         // 抠图
         BufferedImage result = removeBackground(image, backgroundColor);
    
         // 保存结果
         ImageIO.write(result, "PNG", new File(outputPath));
    
         System.out.println("图片抠图完成,已保存为"+outputPath);
         return outputPath;
     } catch (IOException e) {
         e.printStackTrace();
     }
     return inputPath;
    

    }

    // 将前景替换为指定颜色
    public static void replaceForegroundWithColor(String inputPath, String outputPath, String hexColor) {
    try {
    // 加载抠图后的图片
    BufferedImage image = ImageIO.read(new File(inputPath));
    // 将 HEX 颜色转换为 Color 对象
    Color color = Color.decode(hexColor);
    // 遍历每个像素
    for (int y = 0; y < image.getHeight(); y++) {
    for (int x = 0; x < image.getWidth(); x++) {
    int pixel = image.getRGB(x, y);
    // 如果像素不是透明的(即前景像素),替换为指定颜色
    if ((pixel & 0xFF000000) != 0x00) {
    image.setRGB(x, y, color.getRGB()); // 保留透明度,替换颜色
    }
    }
    }

         // 保存结果
         ImageIO.write(image, "PNG", new File(outputPath));
         System.out.println("前景替换为颜色完成,已保存为: " + outputPath);
     } catch (IOException e) {
         e.printStackTrace();
     }
    

    }

    // 自动检测背景色
    private static int detectBackgroundColor(BufferedImage image) {
    Map<Integer, Integer> colorCount = new HashMap<>();
    int width = image.getWidth();
    int height = image.getHeight();

     // 分析边缘像素
     for (int x = 0; x < width; x++) {
         analyzePixel(image.getRGB(x, 0), colorCount); // 上边缘
         analyzePixel(image.getRGB(x, height - 1), colorCount); // 下边缘
     }
     for (int y = 0; y < height; y++) {
         analyzePixel(image.getRGB(0, y), colorCount); // 左边缘
         analyzePixel(image.getRGB(width - 1, y), colorCount); // 右边缘
     }
    
     // 返回出现次数最多的颜色作为背景色
     return colorCount.entrySet().stream()
             .max(Map.Entry.comparingByValue())
             .map(Map.Entry::getKey)
             .orElse(0xFFFFFF); // 如果未检测到背景色,默认使用白色
    

    }

    // 分析像素颜色
    private static void analyzePixel(int pixel, Map<Integer, Integer> colorCount) {
    colorCount.put(pixel, colorCount.getOrDefault(pixel, 0) + 1);
    }

    // 移除背景
    private static BufferedImage removeBackground(BufferedImage image, int backgroundColor) {
    BufferedImage result = new BufferedImage(
    image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
    for (int y = 0; y < image.getHeight(); y++) {
    for (int x = 0; x < image.getWidth(); x++) {
    int pixel = image.getRGB(x, y);
    // 如果像素颜色接近背景色,则设置为透明
    if (isCloseToBackground(pixel, backgroundColor)) {
    result.setRGB(x, y, 0x00FFFFFF); // 设置为完全透明
    } else {
    result.setRGB(x, y, pixel); // 保留前景像素
    }
    }
    }
    return result;
    }

    // 判断像素是否接近背景色
    private static boolean isCloseToBackground(int pixel, int backgroundColor) {
    int threshold = 30; // 颜色相似度阈值
    int redDiff = Math.abs(((pixel >> 16) & 0xFF) - ((backgroundColor >> 16) & 0xFF));
    int greenDiff = Math.abs(((pixel >> 8) & 0xFF) - ((backgroundColor >> 8) & 0xFF));
    int blueDiff = Math.abs((pixel & 0xFF) - (backgroundColor & 0xFF));
    return redDiff < threshold && greenDiff < threshold && blueDiff < threshold;
    }
    }

posted @   曾曾曾zzq  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示