2017-09-18 4 views
0

Bonjour J'ai un problème avec la conversion de mon tampon de données 4 bits en WritableRaster. Résolution d'image: 1024x768 (786432)BufferedImage à partir du tampon de données 4 bits

Voici la description de ce que je fais.

1) Créer 4 bits BufferedImage

bit4Image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY, MY_BIT_4_COLOR_MODEL); 
Graphics graphics = bit4Image.getGraphics(); 
graphics.drawImage(originalImage, 0, 0, null); 
graphics.dispose(); 
//4-bit BufferedImage created. 4-bit BufferedImage is properly made cause it can be saved to hdd and looks good 

2) Obtenir tableau d'octets de DataBuffer de 4 bits

byte[] pixelData = ((DataBufferByte) bit4Image.getRaster().getDataBuffer()).getData(); 
// pixelData length is 393216 

3) Maintenant, je veux créer BufferedImage à partir de ce tableau d'octets pixelData

BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY, MY_BIT_4_COLOR_MODEL); 
DataBufferByte buffer = new DataBufferByte(pixelData, pixelData.length); 
WritableRaster raster = Raster.createInterleavedRaster(buffer, width, height, width, 1, new int[]{0}, new Point(0, 0)); 
dest.setData(raster); 

Le problème est lorsque j'appelle Raster.createInterleavedRaster. Exception: java.awt.image.RasterFormatException: Data array too small (should be > 786431)

J'ai aussi essayé quelque chose comme ça

BufferedImage dest = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY, MY_BIT_4_COLOR_MODEL); 
dest.getRaster().setDataElements(0, 0, width, height, pixelData); 

Mais celui-ci me donne l'échec similaire:
java.lang.ArrayIndexOutOfBoundsException: 393216

Quelqu'un pourrait-il me donner un indice ou montrer le bon façon de définir cette pixelData 4 bits à WritableRaster?

+1

Pour une meilleure aide plus tôt, un poster [MCVE] ou [Short, autoportantes correcte Exemple] (http://www.sscce.org/). –

Répondre

0

Résolu. Je devais créer WritableRaster avec lui donnant SampleModel:
SampleModel sm = MY_BIT_4_COLOR_MODEL.createCompatibleSampleModel(width, height); WritableRaster wr = Raster.createWritableRaster(sm, buffer, new Point(0,0));

0

Le code initial que vous aviez presque travaillé, le seul problème est que vous avez essayé de créer une trame « entrelacée ». Pour les images de palette (IndexColorModel), vous avez généralement un seul échantillon (l'index de la palette) par pixel, donc il n'y a pas d'échantillons à entrelacer. Au lieu de cela, vos données de pixel sont de 4 bits/pixel, stockées sous la forme de deux pixels par octet. Stocker plus d'échantillons par unité de stockage est souvent appelé "emballé". Cela signifie que vous devez créer un raster "compressé" en utilisant l'une des méthodes Raster.createPackedRaster.

Voici un complet exemple runable:

public static void main(String[] args) { 
     int width = 100; 
     int height = 100; 

     // Create initial 4 bit image 
     IndexColorModel icm = new IndexColorModel(4, 16, new int[16], 0, false, -1, DataBuffer.TYPE_BYTE); 
     BufferedImage bit4Image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_BINARY, icm); 

     // ...you probably do something in between here 

     // Get the pixel data 
     byte[] pixelData = ((DataBufferByte) bit4Image.getRaster().getDataBuffer()).getData(); 

     // ...you probably do something in between here 

     // Create a data buffer around the array, wrap in raster 
     DataBufferByte buffer = new DataBufferByte(pixelData, pixelData.length); 
     WritableRaster raster = Raster.createPackedRaster(buffer, width, height, 4, null); 

     // Finally create a copy of the image, sharing pixel data 
     BufferedImage copy = new BufferedImage(icm, raster, icm.isAlphaPremultiplied(), null); 
     System.out.println("copy: " + copy); 
    }