byte[] aus einem BufferedImage

FerFemNemBem

Bekanntes Mitglied
Halloechen,

ich habe ein Problem damit, folgende Methode "umzudrehen":

Java:
private BufferedImage getImageFromImageData(byte[] imageData, int imageWidth, int imageHeight)
    {  
        ByteBuffer byteBuffer = ByteBuffer.wrap(imageData);
        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
        ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
        short[] shortImageData = new short[shortBuffer.capacity()];
        for(int i=0; i<shortImageData.length; i++)
        {
            shortImageData[i] = shortBuffer.get(i);
        }
        
        ColorModel cm = new DirectColorModel(16, 0xF800, 0x7E0, 0x1F);      
        DataBufferUShort db = new DataBufferUShort(shortImageData, shortImageData.length);
        
        // hack to workaround an iTunes/iPod bug
        // if width or hight not even - add 1
        if((imageWidth % 2 != 0) || (imageHeight % 2 != 0))
        {
            if (imageWidth % 2 != 0) imageWidth = imageWidth+1;
            if (imageHeight % 2 != 0) imageHeight = imageHeight+1;
            short[] shortImageDataFixed = new short[shortImageData.length+(imageWidth*imageHeight/2)];    
            System.arraycopy(shortImageData, 0, shortImageDataFixed, 0, shortImageData.length); 
            db = new DataBufferUShort(shortImageDataFixed, shortImageDataFixed.length); 
        }

        SampleModel sm = cm.createCompatibleSampleModel(imageWidth, imageHeight);
        WritableRaster wr = Raster.createWritableRaster(sm, db, null);
        BufferedImage bufferedImage = new BufferedImage(cm, wr, false, null);

        return bufferedImage;   
    }

Mein grosses Problem an der Stelle ist es, aus dem DataBufferUShort, welches mir das WritableRaster bietet, ein byte[] zu machen.

Folgender Ansatz geht jedenfalls nicht:

Java:
    private byte[] getImageDataFromImage(BufferedImage bufferedImage)
    {
        byte[] imageData = new byte[]{};
        WritableRaster wr = bufferedImage.getRaster();        
        DataBufferUShort dataBufferUShort = (DataBufferUShort)wr.getDataBuffer();
        
        short[] shortData = dataBufferUShort.getData();
        
        byte[] test = new byte[shortData.length];
        for (int i=0; i<shortData.length; i++)
        {
            test[i] = (byte)shortData[i];
        }

        ByteBuffer byteBuffer = ByteBuffer.wrap(test);
        byteBuffer.order(ByteOrder.BIG_ENDIAN);
        
        imageData = byteBuffer.array();
        return imageData;
    }

Wuerde mich ueber den ein oder anderen Tip freuen.

Achso, hallo erstmal ans Forum, ich bin der Jan. 😉

Gruss, FFNB.
 
du hast zwischendurch ein Short-Array, in welchem immer zwei Bytes stehen, beim Rückschritt liest du aber jeweils nur ein Byte heraus,
habe mal ein paar byte-Befehle dazu zusammengetippt, so dass es für mein einfaches Beispiel passt,

ob das mit beliebigen Bytes, negativen Werten, LITTLE_ENDIAN usw. oder gar beim 'hack to workaround' hinkommt?..
vielleicht kann ShortBuffer dabei auch noch helfen, habe aber auf die Schnelle nix gesehen

Java:
public class Test
{
    public static void main(String[] args)
    {

        byte[] b = new byte[] {4, 5, 6, 7, 8, 9};
        BufferedImage bi = getImageFromImageData(b, 2, 2);
        System.out.println("back");
        b = getImageDataFromImage(bi);
        System.out.println(Arrays.toString(b));
    }

    private static byte[] getImageDataFromImage(BufferedImage bufferedImage)
    {
        WritableRaster wr = bufferedImage.getRaster();
        DataBufferUShort dataBufferUShort = (DataBufferUShort)wr.getDataBuffer();

        short[] shortData = dataBufferUShort.getData();
        System.out.println("short: " + Arrays.toString(shortData));

        byte[] test = new byte[shortData.length * 2];
        for (int i = 0; i < shortData.length; i++)
        {
            test[2 * i + 1] = (byte)(shortData[i] / 256);
            test[2 * i] = (byte)(shortData[i] - test[2 * i + 1] * 256);
        }

        ByteBuffer byteBuffer = ByteBuffer.wrap(test);
        byteBuffer.order(ByteOrder.BIG_ENDIAN);
        byte[] imageData = byteBuffer.array();
        return imageData;
    }

    private static BufferedImage getImageFromImageData(byte[] imageData, int imageWidth, int imageHeight)
    {
        ByteBuffer byteBuffer = ByteBuffer.wrap(imageData);
        byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
        ShortBuffer shortBuffer = byteBuffer.asShortBuffer();
        short[] shortImageData = new short[shortBuffer.capacity()];
        for (int i = 0; i < shortImageData.length; i++)
        {
            shortImageData[i] = shortBuffer.get(i);
        }

        ColorModel cm = new DirectColorModel(16, 0xF800, 0x7E0, 0x1F);
        DataBufferUShort db = new DataBufferUShort(shortImageData, shortImageData.length);

        // hack to workaround an iTunes/iPod bug
        // if width or hight not even - add 1
        if ((imageWidth % 2 != 0) || (imageHeight % 2 != 0))
        {
            if (imageWidth % 2 != 0) imageWidth = imageWidth + 1;
            if (imageHeight % 2 != 0) imageHeight = imageHeight + 1;
            short[] shortImageDataFixed = new short[shortImageData.length + (imageWidth * imageHeight / 2)];
            System.arraycopy(shortImageData, 0, shortImageDataFixed, 0, shortImageData.length);
            db = new DataBufferUShort(shortImageDataFixed, shortImageDataFixed.length);
        }
        System.out.println("short: " + Arrays.toString(shortImageData));

        SampleModel sm = cm.createCompatibleSampleModel(imageWidth, imageHeight);
        WritableRaster wr = Raster.createWritableRaster(sm, db, null);
        BufferedImage bufferedImage = new BufferedImage(cm, wr, false, null);

        return bufferedImage;
    }
}
 
Halloechen,

ich wollte mich nur nochmal kurz zu einer Korrektur melden (falls noch einmal jemand vor dem Problem stehen sollte). Die von SlaterB vorgeschlagenen Loesung:

Code:
        for (int i = 0; i < shortData.length; i++)
        {
            test[2 * i + 1] = (byte)(shortData[i] / 256);
            test[2 * i] = (byte)(shortData[i] - test[2 * i + 1] * 256);
        }
funktioniert nicht in allen Faellen.
So geht es dann:

Code:
        for (int i = 0; i < shortData.length; i++)
        {
            test[2 * i + 1] = (byte)(shortData[i] >> 8);
            test[2 * i]   = (byte)(shortData[i] & 0xff);
        }

Trotzdem nochmal vielen Dank fuer die Prompte Hilfe hier im Forum!

Gruss, FFNB.
 

Neue Themen


Zurück
Oben