Java BufferedImage地图颜色

问题描述 投票:0回答:2

我正在尝试编写一个程序,将bufferedImage作为输入,并将所有黑色关闭颜色(R <32,G <32,B <32)映射为黑色,将其他颜色映射为白色以用于OCR(OCR引擎需要BufferedImage作为输入)。有没有办法在不迭代像素的情况下做到这一点?即,我试过了

public static BufferedImage BlackAndWhite(BufferedImage image) {

    ColorModel model = new BlackWhiteColorModel(DataBuffer.TYPE_INT);
    WritableRaster raster = image.getRaster();

    BufferedImage newImage = new BufferedImage(model, raster, false, null);

    return newImage;
}

其中BlackWhiteColorModel定义为

public class BlackWhiteColorModel extends ColorModel {

public BlackWhiteColorModel(int bits) {
    super(bits);
}

@Override
public int getRed(int pixel) {
    int[] rgb = getRgb(pixel);

    if (rgb[0] < 32 && rgb[1] < 32 && rgb[2] < 32) {
        return 0;
    } else {
        return 255;
    }
}

@Override
public int getGreen(int pixel) {
    int[] rgb = getRgb(pixel);

    if (rgb[0] < 32 && rgb[1] < 32 && rgb[2] < 32) {
        return 0;
    } else {
        return 255;
    }
}

@Override
public int getBlue(int pixel) {
    int[] rgb = getRgb(pixel);

    if (rgb[0] < 32 && rgb[1] < 32 && rgb[2] < 32) {
        return 0;
    } else {
        return 255;
    }
}

@Override
public int getAlpha(int pixel) {
    return pixel;
}

private int[] getRgb(int pixel) {
    int r = (pixel) & 0xFF;
    int g = (pixel >> 8) & 0xFF;
    int b = (pixel >> 16) & 0xFF;
    int a = (pixel >> 24) & 0xFF;

    return new int[]{r, g, b, a};
}



}

但是,我最终得到了isCompatibleRasterException。有人能给我一些建议吗?

java image-processing colors
2个回答
0
投票

(1)您没有实施合同中的一种方法:isCompatibleRaster。这是一个过于乐观的实现,在您的问题陈述中运行良好:

@Override
public boolean isCompatibleRaster(Raster raster) {
    return true;
}

(2)getRedgetGreengetBlue具有相同的代码。这是一个完整的程序,它将公共代码分解为一个名为getColor的新方法。该程序运行没有错误:

import java.awt.*;
import java.awt.image.*;

public class BlackWhiteColorModel extends ColorModel {
    public static void main(String[] args) {
        BufferedImage bufferedImage = new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB);
         Graphics g = bufferedImage.getGraphics();
         g.drawString("Hello, World", 20,20);
        blackAndWhite(bufferedImage);
    }

    public static BufferedImage blackAndWhite(BufferedImage image) {
        ColorModel model = new BlackWhiteColorModel(DataBuffer.TYPE_INT);
        WritableRaster raster = image.getRaster();

        BufferedImage newImage = new BufferedImage(model, raster, false, null);

        return newImage;
    }

    public BlackWhiteColorModel(int bits) {
        super(bits);
    }

    private int getColor(int pixel) {
        int[] rgb = getRgb(pixel);

        if (rgb[0] < 32 && rgb[1] < 32 && rgb[2] < 32) {
            return 0;
        } else {
            return 255;
        }
    }

    @Override
    public int getRed(int pixel) {
        return getColor(pixel);
    }

    @Override
    public int getGreen(int pixel) {
        return getColor(pixel);
    }

    @Override
    public int getBlue(int pixel) {
        return getColor(pixel);
    }

    @Override
    public int getAlpha(int pixel) {
        return pixel;
    }

    @Override
    public boolean isCompatibleRaster(Raster raster) {
        return true;
    }

    private int[] getRgb(int pixel) {
        int r = (pixel) & 0xFF;
        int g = (pixel >> 8) & 0xFF;
        int b = (pixel >> 16) & 0xFF;
        int a = (pixel >> 24) & 0xFF;

        return new int[]{r, g, b, a};
    }
}

0
投票

你想要的是一个阈值操作,例如:enter image description here

我想你不想因为性能问题而迭代像素。如果这是真的,我强烈建议你像这样使用OpenCV

BufferedImage image = null; //use your image here
//Convert image to OpenCv Mat
byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData();
Mat mat = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3);
mat.put(0, 0, pixels);

//do something with the Mat e.g:
Imgproc.threshold(...); 

//Convert back
mat.get(0, 0, pixels);

特别是如果您进行更多图像处理,性能至少要快10倍

© www.soinside.com 2019 - 2024. All rights reserved.