将图片红色文字转黑色、黑背景转白色的Java代码问题求助
解决黑白图片颜色反转问题
原需求:将黑色背景、红色文字的图片转换为白色背景、黑色文字,但现有代码生成了白色文字、黑色背景的反效果。
问题根源
使用BufferedImage.TYPE_BYTE_BINARY时,Java会以默认阈值(127)判定像素的黑白:原图片中红色文字亮度较高,被识别为白色;黑色背景亮度低,被识别为黑色,最终结果与预期相反。
两种修复方案
方案一:逐像素反转黑白
通过遍历每个像素,计算灰度值后反转颜色:
import java.awt.Color; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class BlackAndWhiteTest { public static void main(String[] args) throws IOException { File file = new File("C://picw//screenshot.png"); BufferedImage originalImage = ImageIO.read(file); int width = originalImage.getWidth(); int height = originalImage.getHeight(); BufferedImage reversedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int pixel = originalImage.getRGB(x, y); Color color = new Color(pixel); // 计算像素灰度值 int gray = (color.getRed() + color.getGreen() + color.getBlue()) / 3; // 反转颜色:亮像素转黑,暗像素转白 int newGray = gray > 127 ? 0 : 255; reversedImage.setRGB(x, y, new Color(newGray, newGray, newGray).getRGB()); } } ImageIO.write(reversedImage, "png", new File("C://picw//newscreenshot.png")); } }
方案二:自定义二进制颜色模型
通过修改IndexColorModel,直接反转黑白像素的映射关系:
import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.awt.image.IndexColorModel; import java.io.File; import java.io.IOException; import javax.imageio.ImageIO; public class BlackAndWhiteTest { public static void main(String[] args) throws IOException { File file = new File("C://picw//screenshot.png"); BufferedImage originalImage = ImageIO.read(file); int width = originalImage.getWidth(); int height = originalImage.getHeight(); // 创建反转的颜色映射:索引0对应白色,索引1对应黑色 byte[] white = {(byte) 255, (byte) 255, (byte) 255}; byte[] black = {0, 0, 0}; IndexColorModel reversedModel = new IndexColorModel(1, 2, white, black); BufferedImage blackAndWhiteImg = new BufferedImage( width, height, BufferedImage.TYPE_BYTE_BINARY, reversedModel); Graphics2D graphics = blackAndWhiteImg.createGraphics(); graphics.drawImage(originalImage, 0, 0, null); graphics.dispose(); ImageIO.write(blackAndWhiteImg, "png", new File("C://picw//newscreenshot.png")); } }
补充说明
- 方案一的阈值(127)可根据实际图片亮度调整,适配不同场景。
- 方案二更贴合原有代码逻辑,无需逐像素遍历,效率更高。
内容的提问来源于stack exchange,提问作者rich25
相关产品推荐
相关产品推荐

