一个亲戚让我帮他把照片里的红色印章抠出来,,,记录下处理过程,代码如下,可直接用:
public static void signatureProcess(String sourceImagePath, String targetImagePath) {Graphics2D graphics2D = null;try {File imageFile = new File(sourceImagePath);BufferedImage sourceBufferIamge = ImageIO.read(imageFile);//新图大小与原图保持一致int targetImageWidth = sourceBufferIamge.getWidth();int targetImageHeight = sourceBufferIamge.getHeight();BufferedImage targetBufferImage = new BufferedImage(targetImageWidth, targetImageHeight, BufferedImage.TYPE_4BYTE_ABGR);graphics2D = targetBufferImage.createGraphics();graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);int targetW = targetBufferImage.getWidth();int targetH = targetBufferImage.getHeight();int targetMinX = targetBufferImage.getMinX();int targetMinY = targetBufferImage.getMinY();for (int i = targetMinX; i < targetW; i++) {for (int j = targetMinY; j < targetH; j++) {// 得到原图像素(i,j)上的RGB值int pixel = sourceBufferIamge.getRGB(i, j);Color color = new Color(pixel);float[] hsbvals=new float[3];float[] floats = Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(), hsbvals);int red = (pixel >> 16) & 0xFF;// 判断是否为红色印章if (red > 200 && colorInRange(floats)) { //双重判断,精细一点 可以根据需要调整阈值targetBufferImage.setRGB(i, j, pixel);} else {// 不是红色,设置为透明targetBufferImage.setRGB(i, j, 0x00000000);}}}// 保存到新文件FileOutputStream ops = new FileOutputStream(new File(targetImagePath));ImageIO.write(targetBufferImage, "png", ops);ops.flush();ops.close();}catch (Exception e) {e.printStackTrace();}finally {if (graphics2D != null) {graphics2D.dispose();}}}private static Boolean colorInRange( float[] floats){if (0.90< floats[0]) {return true;}return false;}
运行效果(章名打了马赛克),左变为抠出的章,右边为原图,如果抠图效果不好,调整代码判断阈值,最好选清晰的色差大的抠图: