首页 > 其他分享 >图片抠图和换色

图片抠图和换色

时间:2024-12-30 16:55:15浏览次数:1  
标签:backgroundColor int image BufferedImage colorCount 换色 pixel 图片

好久没记录了,今天找抠图接口实在找的烦,市面上的免费抠图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;
    }
    }

标签:backgroundColor,int,image,BufferedImage,colorCount,换色,pixel,图片
From: https://www.cnblogs.com/zzqcupidzhq/p/18641680

相关文章

  • java 将指定文件夹内的所有图片 拼接为gif
    引入依赖<dependency><groupId>com.github.jai-imageio</groupId><artifactId>jai-imageio-core</artifactId><version>1.4.0</version></dependency>工具类指定图片文件夹......
  • uView自定义底部导航栏发生错误:不显示图片和文本但是能正常跳转页面
    今天写前端发现原生导航栏只能在一个页面显示而不能在多个页面显示导航栏,所以只能用uView2.x的自定义导航栏来完成这个需求,遇到以下问题:底部导航栏图片和文本不显示但是点击却可以正常条状页面的问题:错误原因:在page.json内配置了"tabBar"属性这个不可或缺,没有这个不能正......
  • 图片PDF转换器
    图片PDF转换器python3.7环境安装python3-mpipinstall-ihttps://mirrors.aliyun.com/pypi/simple/Pillow==9.5.0python3-mpipinstall-ihttps://mirrors.aliyun.com/pypi/simple/reportlab==4.2.5图片PDF转换器.py#!/usr/bin/python#-*-coding:UTF-8-*-......
  • 网站无法上传图片的原因及解决方案
    首先,检查服务器的文件上传权限。确保服务器上的目标目录具有适当的读写权限,特别是对于PHP、Python等动态语言生成的文件。权限设置不当可能导致文件无法正常上传。一般情况下,文件权限应设置为644,目录权限应设置为755。可以通过FTP客户端或SSH命令修改文件权限。其次,确认PHP或相关......
  • 为什么我的网站图片加载速度非常慢?
    网站图片加载速度缓慢不仅会影响用户体验,还可能导致搜索引擎排名下降。为了提高图片加载速度,您可以从以下几个方面入手进行优化:压缩图片文件:图片文件过大是导致加载慢的主要原因之一。使用专业的图片压缩工具(如TinyPNG、ImageOptim等)可以在不影响视觉质量的前提下显著减小文件......
  • 如何解决虚拟主机上传图片失败的问题?
    您好,当您在虚拟主机中上传图片时遇到失败问题,可以按照以下步骤进行排查和解决,确保能够正常上传图片:确认文件权限:检查目标文件和目录的权限设置。有时,文件或目录的权限设置不当会导致无法上传。确保您有足够的权限(如读写权限)来操作这些文件。常见的权限设置如下:文件权限:-rw-......
  • 网站图片上传不显示的原因及解决办法
    网站图片上传后无法显示是一个常见的问题,尤其是在涉及到服务器迁移或环境变化的情况下。根据您的描述,图片上传过程中出现“目录创建失败”的提示,这表明问题可能出现在服务器端而非前端代码层面。下面我们将详细探讨可能导致此类问题的各种原因,并提供相应的解决方案,帮助您快速恢复......
  • 如何在canvas中显示图片?
    在前端开发中,使用HTML的<canvas>元素来显示图片是一个常见的任务。以下是一个简单的步骤说明,以及一个示例代码,演示如何在canvas中显示图片:步骤创建Canvas元素:在HTML文件中添加一个<canvas>元素。为该元素指定一个ID,以便在JavaScript中引用它。获取Canvas上下文:在Java......
  • [开源]用QT+OPENCV做了一个图片处理软件
    yusongmin1/QT_OPENCV界面如下基本功能,基本上没有基于opencv的库函数,手搓关于常见的传统图片处理的算法的开发,包括了内置图片,图片加载与保存,图片变换GRB2GRAY,RGB2HSV镜像,水平镜像,垂直镜像,负90度到正90度之间的旋转,阈值分割,反向腐蚀膨胀,开运算闭运算直方图......
  • 使用 `hash-wasm` 的 `createMD5`方法,生成md5值,批处理500张图片会报错, `RangeError: W
    处理大量文件时遇到RangeError:WebAssembly.instantiate():Outofmemory错误,通常是因为一次性创建了过多的WebAssembly实例,导致内存不足。每个createMD5()调用都会创建一个新的WebAssembly实例,这对于大量的并发操作来说是不可行的。为了优化代码并避免此问题,可以考虑......