2012-02-03 12 views
11

Mam obraz binarny RGB bufferedImage.
Chcę przekonwertować bImg na szary obraz.przekonwertować obraz RGB na skalę szarości Obraz zmniejszający pamięć w java

Próbowałem tego grayIm, ale nie mogę ustawić wartości skali szarości dla tego grayIm.

+0

Możliwy duplikat - http://stackoverflow.com/questions/6471340/how-do-i-desaturate-a-bufferedimage-in-java/6471524#6471524 – mre

+0

Co _ "Nie mogę ustawić skali szarości wartości dla tego szareIm "_ mean? –

Odpowiedz

25

Jednym ze sposobów może być do konwersji przestrzeni kolorów (słabe wyniki):

ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY); 
ColorConvertOp op = new ColorConvertOp(cs, null); 
BufferedImage image = op.filter(bufferedImage, null); 

Innym byłoby użyć BufferedImage, jak to zrobić (lepszą wydajność):

BufferedImage image = new BufferedImage(width, height, 
    BufferedImage.TYPE_BYTE_GRAY); 
Graphics g = image.getGraphics(); 
g.drawImage(colorImage, 0, 0, null); 
g.dispose(); 

Last but not least, najlepsza wydajność stosuje GrayFilter:

ImageFilter filter = new GrayFilter(true, 50); 
ImageProducer producer = new FilteredImageSource(colorImage.getSource(), filter); 
Image mage = Toolkit.getDefaultToolkit().createImage(producer); 

źródło: http://www.codebeach.com/2008/03/convert-color-image-to-gray-scale-image.html

edytuj: za komentarz Marka.

+1

W trzeciej metodzie createImage nie jest zdefiniowany. 'this' powinno być' Toolkit.getDefaultToolkit() ' –

+0

Czy trzecia implementacja ma znacznie lepszą wydajność niż poniższe rozwiązanie? –

20

UWAGA: To nie jest to, co PO poprosił (ponieważ nie nie zmniejszyć zużycie pamięci), ale będę go tu zostawić, bo takich ludzi jak ten ręcznym podejściu per-pixel.


To bardzo proste. Chodzi o to, aby powtórzyć każdy piksel obrazu i zmienić go na odpowiednik skali szarości.

public static void makeGray(BufferedImage img) 
{ 
    for (int x = 0; x < img.getWidth(); ++x) 
    for (int y = 0; y < img.getHeight(); ++y) 
    { 
     int rgb = img.getRGB(x, y); 
     int r = (rgb >> 16) & 0xFF; 
     int g = (rgb >> 8) & 0xFF; 
     int b = (rgb & 0xFF); 

     int grayLevel = (r + g + b)/3; 
     int gray = (grayLevel << 16) + (grayLevel << 8) + grayLevel; 
     img.setRGB(x, y, gray); 
    } 
} 

Jednak nie zmniejsza to pamięci. Aby skutecznie zmniejszyć zużycie pamięci, wykonaj ten sam proces, ale użyj wyjścia buforowego w skali szarości jako obrazu wyjściowego.

+2

Ale to zmniejsza pamięć @Martijn Courteaux –

+7

W rzeczywistości konwersja w skali szarości nie jest prostą średnią kanałów R, G i B, ponieważ niebieski przyczynia się do najmniejszej percepcji jasności, podczas gdy zielony przyczynia się najbardziej. Aby uzyskać dokładną reprezentację natężenia światła na obrazie w skali szarości, potrzebna jest średnia ważona. Użyj 0.2126R + 0.7152G + 0.0722B –

+0

@ Mr.WorshipMe: Nice! Zdaję sobie sprawę z tego zjawiska. Jakieś zasoby na waszych wagach? –

Powiązane problemy