java g.setcolor_Java Graphics - 如何设置Color作为int值用于setRGB(int x,int y,int rgb)方法? - Java...

此博客展示了一段Java代码,利用Java的AWT和ImageIO库进行图像绘制。代码中创建了一个BufferedImage对象,使用Graphics的setColor方法设置颜色,绘制矩形和椭圆形,最后将图像转换为灰度图并保存为PNG文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import java.awt.Color;

import java.awt.Graphics;

import java.awt.image.BufferedImage;

import java.awt.image.ColorConvertOp;

import java.io.File;

import javax.imageio.ImageIO;

public class Main {

public static void main(String[] args) throws Exception{

int size = 120;

int pad = 10;

BufferedImage bi = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);

Graphics g = bi.createGraphics();

g.setColor(Color.WHITE);

g.fillRect(0, 0, size, size);

g.setColor(Color.YELLOW);

g.fillOval(pad, pad, size - (2 * pad), size - (2 * pad));

g.dispose();

BufferedImage image2 = new BufferedImage(bi.getWidth(), bi.getHeight(),

BufferedImage.TYPE_BYTE_GRAY);

ColorConvertOp op = new ColorConvertOp(bi.getColorModel().getColorSpace(),

image2.getColorModel().getColorSpace(), null);

op.filter(bi, image2);

ImageIO.write(image2, "png", new File("c:/Java_Dev/image2.png"));

}

}

public static void createMarkForPic2(String sourcePath, String outputPath, String watermarkText, Color textColor, float opacity, String fontName, int fontSize, int spacing, Color borderColor, String fileExtension, Map<String, Object> params) { // 强制设置为20pt字体 fontSize = 20; try { // 读取原始图片 BufferedImage sourceImage = ImageIO.read(new File(sourcePath)); int width = sourceImage.getWidth(); int height = sourceImage.getHeight(); // 创建画布 BufferedImage watermarkedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = watermarkedImage.createGraphics(); g2d.drawImage(sourceImage, 0, 0, null); // 智能自适应方案 int baseSize = Math.min(width, height); int adaptiveFontSize = (int)(baseSize * 0.03); // 根据图片尺寸动态计算 fontSize = Math.max(20, adaptiveFontSize); // 至少20pt // 设置字体(加粗) Font font = new Font(fontName, Font.BOLD, fontSize); g2d.setFont(font); // 计算水印位置(智能居中偏左上) FontMetrics metrics = g2d.getFontMetrics(); int textWidth = metrics.stringWidth(watermarkText); int textHeight = metrics.getHeight(); int posX = width / 20; // 水平位置:1/20宽度处 int posY = textHeight + (height / 20); // 垂直位置:文字高度+1/20高度处 // 自适应透明度(深色背景用高透明度,浅色背景用低透明度) float adaptiveOpacity = calculateAdaptiveOpacity(sourceImage, posX, posY, textWidth, textHeight); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, adaptiveOpacity)); // 绘制水印(白字黑边) g2d.setColor(Color.BLACK); g2d.drawString(watermarkText, posX-1, posY-1); g2d.drawString(watermarkText, posX+1, posY-1); g2d.drawString(watermarkText, posX-1, posY+1); g2d.drawString(watermarkText, posX+1, posY+1); g2d.setColor(Color.WHITE); g2d.drawString(watermarkText, posX, posY); g2d.dispose(); // 保存图片 String formatName = fileExtension.startsWith(".") ? fileExtension.substring(1) : fileExtension; ImageIO.write(watermarkedImage, formatName, new File(outputPath)); } catch (Exception e) { e.printStackTrace(); } } // 智能计算背景区域平均亮度(用于确定最佳透明度) private static float calculateAdaptiveOpacity(BufferedImage image, int x, int y, int width, int height) { // 采样水印区域背景色 int sampleCount = 0; long totalBrightness = 0; int endX = Math.min(x + width, image.getWidth()); int endY = Math.min(y + height, image.getHeight()); for (int i = x; i < endX; i += 5) { // 每隔5像素采样 for (int j = y; j < endY; j += 5) { int rgb = image.getRGB(i, j); int r = (rgb >> 16) & 0xFF; int g = (rgb >> 8) & 0xFF; int b = rgb & 0xFF; totalBrightness += (r + g + b) / 3; sampleCount++; } } if (sampleCount == 0) return 0.7f; float avgBrightness = totalBrightness / (float)sampleCount; // 亮度越高(背景越亮),透明度越低(水印越明显) return avgBrightness > 150 ? 0.8f : avgBrightness > 100 ? 0.7f : 0.6f; }这段添加水印的代码需要修改为如果已存在水印就先清除水印再重新添加水印,避免重复添加水印导致水印重叠看不清,可以接受每次添加水印时如果识别到有水印存在,将水印区域设置成白色,再重新添加水印的方案,或者有其他更好的方案也行
07-12
/** * ocr配置 / @PostConstruct public void initOcrEngine() { tesseract = new Tesseract(); //语言包路径和支持语言 tesseract.setDatapath(tessDataPath); tesseract.setLanguage(“eng+chi_sim”); tesseract.setPageSegMode(6); //自动页面分割 tesseract.setOcrEngineMode(3); //LSTM引擎 } /* * OCR识别图片内容 */ private String extractImageText(MultipartFile file) { try (InputStream is = file.getInputStream()) { BufferedImage image = ImageIO.read(is); if (image == null) { return MessageUtils.message(“Image.parsing.failed”); } // image = increaseVerticalSpacingBetweenText(image, 50); // image = increaseHorizontalSpacing(image, 20); // image=fixCharacterSticking(image); saveDebugImage(image, “3_final.png”); String result = tesseract.doOCR(image); //OCR识别 result = postProcess(result); result = result.replaceAll(“\s+”, " ").trim(); System.out.println(“图片内容:\n” + result); return result; } catch (Exception e) { e.printStackTrace(); return MessageUtils.message(“file.read.picture.error”); } } private void saveDebugImage(BufferedImage img, String filename) throws IOException { // 保存到项目目录下的debug文件夹 String basePath = “D:/pdf/debug/”; File outputDir = new File(basePath); if (!outputDir.exists()) outputDir.mkdirs(); String fullPath = basePath + filename; ImageIO.write(img, “png”, new File(fullPath)); } public BufferedImage fixCharacterSticking(BufferedImage original) { // 1. 灰度化处理 BufferedImage grayscale = toGrayscale(original); // 2. 自适应二化(无OpenCV) BufferedImage binary = adaptiveBinarization(grayscale); // 3. 文本行检测与分割 List<int[]> textLines = detectTextLines(binary); // 4. 垂直间距增强 return addVerticalSpacing(binary, textLines, 15); } // 灰度化处理 private BufferedImage toGrayscale(BufferedImage src) { BufferedImage gray = new BufferedImage( src.getWidth(), src.getHeight(), BufferedImage.TYPE_BYTE_GRAY); Graphics g = gray.getGraphics(); g.drawImage(src, 0, 0, null); g.dispose(); return gray; } // 自适应二化(无OpenCV) private BufferedImage adaptiveBinarization(BufferedImage gray) { int width = gray.getWidth(); int height = gray.getHeight(); BufferedImage binary = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY); // 使用局部阈(7x7窗口) int windowSize = 7; int halfWindow = windowSize / 2; for (int y = halfWindow; y < height - halfWindow; y++) { for (int x = halfWindow; x < width - halfWindow; x++) { // 计算局部区域平均灰度 int sum = 0; for (int j = -halfWindow; j <= halfWindow; j++) { for (int i = -halfWindow; i <= halfWindow; i++) { Color pixel = new Color(gray.getRGB(x + i, y + j)); sum += pixel.getRed(); // 灰度图R=G=B } } int avg = sum / (windowSize * windowSize); // 应用阈(带偏移量) Color current = new Color(gray.getRGB(x, y)); int threshold = Math.max(10, avg - 15); // 动态阈 int newPixel = (current.getRed() < threshold) ? 0 : 0xFFFFFF; binary.setRGB(x, y, newPixel); } } return binary; } // 文本行检测 private List<int[]> detectTextLines(BufferedImage binary) { List<int[]> lines = new ArrayList<>(); int height = binary.getHeight(); int width = binary.getWidth(); boolean inTextLine = false; int lineStart = 0; for (int y = 0; y < height; y++) { int blackCount = 0; for (int x = 0; x < width; x++) { if ((binary.getRGB(x, y) & 0xFFFFFF) == 0) { blackCount++; } } // 检测文本行(黑色像素超过5%) if (blackCount > width * 0.05) { if (!inTextLine) { lineStart = y; inTextLine = true; } } else { if (inTextLine) { lines.add(new int[]{lineStart, y - 1}); inTextLine = false; } } } // 处理最后一行 if (inTextLine) { lines.add(new int[]{lineStart, height - 1}); } return lines; } // 添加垂直间距 private BufferedImage addVerticalSpacing( BufferedImage src, List<int[]> lines, int spacing) { int width = src.getWidth(); int newHeight = src.getHeight() + (lines.size() - 1) * spacing; BufferedImage result = new BufferedImage(width, newHeight, BufferedImage.TYPE_BYTE_BINARY); // 填充白色背景 Graphics2D g = result.createGraphics(); g.setColor(Color.WHITE); g.fillRect(0, 0, width, newHeight); // 复制文本行并添加间距 int currentY = 0; for (int[] line : lines) { int lineHeight = line[1] - line[0] + 1; g.drawImage(src.getSubimage(0, line[0], width, lineHeight), 0, currentY, null); currentY += lineHeight + spacing; } g.dispose(); return result; } 你给我的代码 有上下字符有空隙了 然后也把我的字符给切成两半了
最新发布
07-26
@PostConstruct public void initOcrEngine() { tesseract = new Tesseract(); //语言包路径和支持语言 tesseract.setDatapath(tessDataPath); tesseract.setLanguage("eng+chi_sim"); tesseract.setPageSegMode(6); //自动页面分割 tesseract.setOcrEngineMode(3); //LSTM引擎 } /** * OCR识别图片内容 */ private String extractImageText(MultipartFile file) { try (InputStream is = file.getInputStream()) { BufferedImage image = ImageIO.read(is); if (image == null) { return MessageUtils.message("Image.parsing.failed"); } image = binarizeImage(image, 128); // 二化 image = breakCharacterConnections(image); // 断开粘连 List<Rectangle> regions = findCharacterRegions(image); // 字符级检测 image = addSpacingBetweenCharacters(image, regions, 10); // 插入间距 saveDebugImage(image, "3_final.png"); // 保存最终处理结果 String result = tesseract.doOCR(image); //OCR识别 result = postProcess(result); result = result.replaceAll("\\s+", " ").trim(); System.out.println("图片内容:\n" + result); return result; } catch (Exception e) { e.printStackTrace(); return MessageUtils.message("file.read.picture.error"); } } private void saveDebugImage(BufferedImage img, String filename) throws IOException { // 保存到项目目录下的debug文件夹 String basePath = "D:/pdf/debug/"; File outputDir = new File(basePath); if (!outputDir.exists()) outputDir.mkdirs(); String fullPath = basePath + filename; ImageIO.write(img, "png", new File(fullPath)); } private static BufferedImage binarizeImage(BufferedImage image, int threshold) { int width = image.getWidth(); int height = image.getHeight(); BufferedImage binaryImage = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int argb = image.getRGB(x, y); int gray = (argb >> 16) & 0xff; if (gray < threshold) { binaryImage.setRGB(x, y, Color.BLACK.getRGB()); } else { binaryImage.setRGB(x, y, Color.WHITE.getRGB()); } } } return binaryImage; } public static List<Rectangle> findCharacterRegions(BufferedImage binaryImage) { int width = binaryImage.getWidth(); int height = binaryImage.getHeight(); boolean[][] visited = new boolean[width][height]; List<Rectangle> regions = new ArrayList<>(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (isBlack(binaryImage.getRGB(x, y)) && !visited[x][y]) { // BFS查找连通域 Queue<Point> queue = new LinkedList<>(); queue.add(new Point(x, y)); visited[x][y] = true; int minX = x, maxX = x, minY = y, maxY = y; while (!queue.isEmpty()) { Point p = queue.poll(); for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { int nx = p.x + dx, ny = p.y + dy; if (nx >= 0 && nx < width && ny >= 0 && ny < height && isBlack(binaryImage.getRGB(nx, ny)) && !visited[nx][ny]) { visited[nx][ny] = true; queue.add(new Point(nx, ny)); minX = Math.min(minX, nx); maxX = Math.max(maxX, nx); minY = Math.min(minY, ny); maxY = Math.max(maxY, ny); } } } } // 过滤小面积噪点 if ((maxX - minX + 1) * (maxY - minY + 1) > 20) { regions.add(new Rectangle(minX, minY, maxX - minX + 1, maxY - minY + 1)); } } } } return regions; } private static boolean isBlack(int rgb) { return (rgb & 0xFFFFFF) == 0; // 纯黑色 } public static BufferedImage addSpacingBetweenCharacters(BufferedImage image, List<Rectangle> regions, int spacing) { int width = image.getWidth(); int height = image.getHeight(); BufferedImage newImage = new BufferedImage(width + spacing * regions.size(), height, BufferedImage.TYPE_BYTE_BINARY); Graphics2D g = newImage.createGraphics(); g.setColor(Color.WHITE); g.fillRect(0, 0, newImage.getWidth(), newImage.getHeight()); int offsetX = 0; for (Rectangle r : regions) { // 截取字符区域 BufferedImage charImg = image.getSubimage(r.x, r.y, r.width, r.height); g.drawImage(charImg, offsetX, 0, null); offsetX += r.width + spacing; // 插入间距 } g.dispose(); return newImage; } public static BufferedImage breakCharacterConnections(BufferedImage image) { int width = image.getWidth(); int height = image.getHeight(); BufferedImage result = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY); // 定义3x3结构元素 int[][] kernel = { {1, 1, 1}, {1, 1, 1}, {1, 1, 1} }; // 腐蚀(缩小边缘) BufferedImage eroded = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY); for (int y = 1; y < height - 1; y++) { for (int x = 1; x < width - 1; x++) { boolean allBlack = true; for (int dy = -1; dy <= 1; dy++) { for (int dx = -1; dx <= 1; dx++) { if ((image.getRGB(x + dx, y + dy) & 0xFF) > 0x7F) { allBlack = false; break; } } } eroded.setRGB(x, y, allBlack ? Color.BLACK.getRGB() : Color.WHITE.getRGB()); } } // 膨胀(恢复字符主体) for (int y = 1; y < height - 1; y++) { for (int x = 1; x < width - 1; x++) { boolean anyBlack = false; for (int dy = -1; dy <= 1; dy++) { for (int dx = -1; dx <= 1; dx++) { if ((eroded.getRGB(x + dx, y + dy) & 0xFF) == 0) { anyBlack = true; break; } } } result.setRGB(x, y, anyBlack ? Color.BLACK.getRGB() : Color.WHITE.getRGB()); } } return result; }对嘛
07-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值