简体   繁体   中英

Raw data to JPEG format - JAVA

I tried to convert raw data ByteArray to JPEG format using JPEGEncoder but its too slow in mobile (I've tested it on mobile). How can I do the same thing in java? I will send raw data byte to java and encode it to JPEG with java - I tried some of them as JpegImageEncoder under com.sun.* but it's depreciated in jdk7. How can I do this in java Or any suggestions from Flex mobile developers who have done such thing?

UPDATE: I tried the following code but I'm getting a strange result:

public void rawToJpeg(byte[] rawBytes, int width, int height, File outputFile){

        try{

            BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);

            int count = 0; 
            for(int h=0;h<height;h++){
                for(int w=0;w<width;w++){
                    bi.setRGB(w, h, rawBytes[count++]);
                }
            }


            Graphics2D ig2 = bi.createGraphics();

            Iterator imageWriters = ImageIO.getImageWritersByFormatName("jpeg");
            ImageWriter imageWriter = (ImageWriter) imageWriters.next(); 

            ImageOutputStream ios = ImageIO.createImageOutputStream(outputFile);
            imageWriter.setOutput(ios);
            imageWriter.write(bi);


        }catch(Exception ex){
            ex.printStackTrace();
        }


    }

RESULT: 在此输入图像描述

PS It should be my photo btw :)

Why not use a ByteArrayInputStream with ImageIO ?

You find more Information about ImageIO in the API .

public static void rawToJpeg(byte[] bytes, File outputFile) {
    try {
        BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));
        ImageIO.write(img, "jpg", outputFile);
    } catch (IOException e) {
        // Handle exception
    }
}

bi.setRGB takes a 4 byte "int" value, which is the ARGB 0xAARRGGBB

You then increment your byte offset counter by ONE, so the next pixel will get 0xRRGGBBAA, then 0xGGBBAARR and so forth.

Assuming the byte[] you are passing is in the correct 4 byte format, you need to either be adding 4 to "count" each time, or change what you pass to an int[] (which would actually be more correct, since it really does contain int values).

Hi i was facing same problem, i was setting the width and height values as hardcoded lets say (300,300) causing similar output. then i referenced this link. Raw byte[] to jpeg image you can ignore the bitmap part in it. I am assuming you are also hardcoding the width and height values.

You could try to replace your for-loops by this

for(int w = 0; w < width; w++)
{
    for(int h = 0; h < height; h++)
    {
            //alpha should be eiter 0 or 255
            //if you use the wrong value your image will be transparent

            int alpha = 0 << 8*3;
            int red = rawBytes[count*3 + 0] << 8*2;
            int green = rawBytes[count*3 + 1] << 8*1;
            int blue = rawBytes[count*3 + 2] << 8*0;

            int color = alpha + red + green + blue;

            //color is an int with the format of TYPE_INT_ARGB (0xAARRGGBB)

            bi.setRGB(w, h, color);
            count += 3;
    }
}

Things that may went wrong with your code:

  1. You usually write line by line not row by row

  2. You need to read 3 bytes and build an int instead of writing the bytes directly in your Pixel (TYPE_INT_ARGB)

This link explains TYPE_INT_ARGB: Format of TYPE_INT_RGB and TYPE_INT_ARGB

I hope this helps a bit and isn't too confusing =)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM