2011-06-27 7 views
7

Po niecierpliwością, znalazłem kawałek kodu, który konwertuje BufferedImage do SWT obrazu (nie przeszkadza czytanie go jeszcze):Konwersja z BufferedImage do SWT obrazu

public static ImageData convertToSWT(BufferedImage bufferedImage) { 
    if (bufferedImage.getColorModel() instanceof DirectColorModel) { 
     DirectColorModel colorModel = (DirectColorModel) bufferedImage.getColorModel(); 
     PaletteData palette = new PaletteData(
      colorModel.getRedMask(), 
      colorModel.getGreenMask(), 
      colorModel.getBlueMask() 
     ); 
     ImageData data = new ImageData(
      bufferedImage.getWidth(), 
      bufferedImage.getHeight(), colorModel.getPixelSize(), 
      palette 
     ); 
     WritableRaster raster = bufferedImage.getRaster(); 
     int[] pixelArray = new int[3]; 
     for (int y = 0; y < data.height; y++) { 
      for (int x = 0; x < data.width; x++) { 
       raster.getPixel(x, y, pixelArray); 
       int pixel = palette.getPixel(
        new RGB(pixelArray[0], pixelArray[1], pixelArray[2]) 
       ); 
       data.setPixel(x, y, pixel); 
      } 
     } 
     return data; 
    } else if (bufferedImage.getColorModel() instanceof IndexColorModel) { 
     IndexColorModel colorModel = (IndexColorModel) bufferedImage.getColorModel(); 
     int size = colorModel.getMapSize(); 
     byte[] reds = new byte[size]; 
     byte[] greens = new byte[size]; 
     byte[] blues = new byte[size]; 
     colorModel.getReds(reds); 
     colorModel.getGreens(greens); 
     colorModel.getBlues(blues); 
     RGB[] rgbs = new RGB[size]; 
     for (int i = 0; i < rgbs.length; i++) { 
      rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF); 
     } 
     PaletteData palette = new PaletteData(rgbs); 
     ImageData data = new ImageData(
      bufferedImage.getWidth(), 
      bufferedImage.getHeight(), 
      colorModel.getPixelSize(), 
      palette 
     ); 
     data.transparentPixel = colorModel.getTransparentPixel(); 
     WritableRaster raster = bufferedImage.getRaster(); 
     int[] pixelArray = new int[1]; 
     for (int y = 0; y < data.height; y++) { 
      for (int x = 0; x < data.width; x++) { 
       raster.getPixel(x, y, pixelArray); 
       data.setPixel(x, y, pixelArray[0]); 
      } 
     } 
     return data; 
    } 
    return null; 
} 

(tutaj: http://www.java2s.com/Code/Java/SWT-JFace-Eclipse/ConvertsabufferedimagetoSWTImageData.htm) .

Przetestowałem to i działa dobrze. Problem polega na tym, że go nie rozumiem (przypuszczam, że używa on nieprzetworzonych interfejsów danych do wykonania transferu). Przyszło mi do głowy, że znacznie prostszym rozwiązaniem byłoby napisanie BufferedImage na ByteArrayOutputStream, a następnie odczytanie go z powrotem na obrazie SWT z numerem ByteArrayInputStream. Czy są jakieś problemy z tym rozwiązaniem? A co z prędkością?

Konwersja jest konieczna, ponieważ wszystkie biblioteki zmiany rozmiaru obrazków są dostępne dla AWT, a mimo to wyświetlam obraz z SWT.

Dzięki!

Odpowiedz

6

Złożoność kodu wynika głównie z dwóch możliwych modeli kolorów: BufferedImage. Nie sądzę, że możesz poprawić w tym zakresie. Po pierwsze, użycie pośredniego Stream wymaga, aby dwa systemy obrazów miały wspólny format, a konwersja do/z Stream z pewnością będzie znacznie wolniejsza niż obecny kod.

+0

Dzięki, że doskonale odpowiada na moje pytanie. – Jonah

5

To jest bardziej kompletna wersja ... Ta opublikowana w pytaniu nie działa dla mnie.

/** 
* snippet 156: convert between SWT Image and AWT BufferedImage. 
* <p> 
* For a list of all SWT example snippets see 
* http://www.eclipse.org/swt/snippets/ 
*/ 
public static ImageData convertToSWT(BufferedImage bufferedImage) { 
    if (bufferedImage.getColorModel() instanceof DirectColorModel) { 
     /* 
     DirectColorModel colorModel = (DirectColorModel)bufferedImage.getColorModel(); 
     PaletteData palette = new PaletteData(
       colorModel.getRedMask(), 
       colorModel.getGreenMask(), 
       colorModel.getBlueMask()); 
     ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), 
       colorModel.getPixelSize(), palette); 
     WritableRaster raster = bufferedImage.getRaster(); 
     int[] pixelArray = new int[3]; 
     for (int y = 0; y < data.height; y++) { 
      for (int x = 0; x < data.width; x++) { 
       raster.getPixel(x, y, pixelArray); 
       int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2])); 
       data.setPixel(x, y, pixel); 
      } 
     } 
     */ 
     DirectColorModel colorModel = (DirectColorModel)bufferedImage.getColorModel(); 
     PaletteData palette = new PaletteData(
       colorModel.getRedMask(), 
       colorModel.getGreenMask(), 
       colorModel.getBlueMask()); 
     ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), 
       colorModel.getPixelSize(), palette); 
     for (int y = 0; y < data.height; y++) { 
      for (int x = 0; x < data.width; x++) { 
       int rgb = bufferedImage.getRGB(x, y); 
       int pixel = palette.getPixel(new RGB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF)); 
       data.setPixel(x, y, pixel); 
       if (colorModel.hasAlpha()) { 
        data.setAlpha(x, y, (rgb >> 24) & 0xFF); 
       } 
      } 
     } 
     return data; 
    } 
    else if (bufferedImage.getColorModel() instanceof IndexColorModel) { 
     IndexColorModel colorModel = (IndexColorModel)bufferedImage.getColorModel(); 
     int size = colorModel.getMapSize(); 
     byte[] reds = new byte[size]; 
     byte[] greens = new byte[size]; 
     byte[] blues = new byte[size]; 
     colorModel.getReds(reds); 
     colorModel.getGreens(greens); 
     colorModel.getBlues(blues); 
     RGB[] rgbs = new RGB[size]; 
     for (int i = 0; i < rgbs.length; i++) { 
      rgbs[i] = new RGB(reds[i] & 0xFF, greens[i] & 0xFF, blues[i] & 0xFF); 
     } 
     PaletteData palette = new PaletteData(rgbs); 
     ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), 
       colorModel.getPixelSize(), palette); 
     data.transparentPixel = colorModel.getTransparentPixel(); 
     WritableRaster raster = bufferedImage.getRaster(); 
     int[] pixelArray = new int[1]; 
     for (int y = 0; y < data.height; y++) { 
      for (int x = 0; x < data.width; x++) { 
       raster.getPixel(x, y, pixelArray); 
       data.setPixel(x, y, pixelArray[0]); 
      } 
     } 
     return data; 
    } 
    else if (bufferedImage.getColorModel() instanceof ComponentColorModel) { 
     ComponentColorModel colorModel = (ComponentColorModel)bufferedImage.getColorModel(); 
     //ASSUMES: 3 BYTE BGR IMAGE TYPE 
     PaletteData palette = new PaletteData(0x0000FF, 0x00FF00,0xFF0000); 
     ImageData data = new ImageData(bufferedImage.getWidth(), bufferedImage.getHeight(), 
       colorModel.getPixelSize(), palette); 
     //This is valid because we are using a 3-byte Data model with no transparent pixels 
     data.transparentPixel = -1; 
     WritableRaster raster = bufferedImage.getRaster(); 
     int[] pixelArray = new int[3]; 
     for (int y = 0; y < data.height; y++) { 
      for (int x = 0; x < data.width; x++) { 
       raster.getPixel(x, y, pixelArray); 
       int pixel = palette.getPixel(new RGB(pixelArray[0], pixelArray[1], pixelArray[2])); 
       data.setPixel(x, y, pixel); 
      } 
     } 
     return data; 
    } 
    return null; 
} 
+0

Ciekawość, skąd wziąłeś tę ukończoną wersję? – Galabyca

+1

http://www.eclipse.org/swt/snippets – marcolopes