2017-12-24 12 views
0

Ich versuche ein Programm zu schreiben, das bufferedImage als Eingabe verwendet und alle Schwarzabgleich-Farben (R < 32, B < 32) zu Schwarz und die anderen zu Weiß für diesen Zweck abbildet von OCR (die OCR-Engine nimmt BufferedImage als Eingabe). Gibt es eine Möglichkeit, dies ohne Iteration über Pixel zu tun? nämlich habe ich versucht,Java BufferedImage Kartenfarben

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; 
} 

Wo BlackWhiteColorModel als

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}; 
} 



} 

jedoch definiert ist, ich mit isCompatibleRasterException enden. Könnte mir jemand einen Rat geben?

+0

Sie benötigen ein ** Black & White * * image oder ein ** GrayScale ** one? – STaefi

Antwort

0

(1) Sie haben keine der folgenden Methoden des Vertrags implementiert: isCompatibleRaster. Hier ist eine zu optimistische Implementierung, die in Ordnung gegeben läuft Ihre Problemstellung:

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

(2) getRed, getGreen und getBlue haben den gleichen Code. Hier ist ein komplettes Programm, das den allgemeinen Code in eine neue Methode namens getColor ausgliedert. Dieses Programm läuft ohne Fehler:

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

Danke. Allerdings funktioniert meine Art, ein neues Bild mit einem anderen colorModel zu erstellen, nicht. Wenn ich die Ausgabe von BlackAndWhite (BufferedImage Image) speichern möchte, wird keine Datei erstellt und keine Ausnahme ausgelöst. Auch Texterkennung funktioniert nicht. Würdest du über eine andere (funktionale) Art und Weise wissen, wie man ein neues Bild mit verschiedenen ColorModel, aber denselben Daten erstellt? –

+0

Sie erweitern den Bereich, der die Frage ändert, Bitte akzeptieren Sie diese Antwort und stellen Sie eine neue Frage mit dem erweiterten Bereich. –

0

Was Sie wollen, ist ein Schwellenwertoperation zB: enter image description here

Ich glaube, Sie wollen nicht wegen Performance-Probleme über die Pixel iterieren. Wenn das wahr ist, würde ich empfehlen Ihnen OpenCV wie diese nur zu verwenden:

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); 

Die Leistung vor allem, wenn Sie tun mehr Bildverarbeitung ist mindestens 10-fach schneller

+0

Vielen Dank dafür! Ich würde es während der Ferien überprüfen. –