原始数据转换成JPEG格式 - JAVA

10

我试图使用JPEG编码器将原始数据ByteArray转换为JPEG格式,但在移动设备上速度太慢(我已在移动设备上测试过)。我该如何在Java中完成同样的操作?我将发送原始数据字节到Java并使用Java对其进行编码以生成JPEG - 我尝试了一些类似于com.sun.*下的JpegImageEncoder,但在jdk7中已被弃用。我该如何在Java中完成这个操作,或者有没有Flex移动开发人员可以提供类似的建议?

更新:我尝试了以下代码,但得到了奇怪的结果:

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();
        }


    }

结果:在此输入图片描述

附言:这应该是我的照片:)


我有同样的问题。你找到任何解决方案了吗? - ehsun7b
不,目前我正在客户端进行所有编码,但处理时间很长。 - Zaur Guliyev
对我来说,客户端或服务器都无所谓,你现在使用的是什么语言和技术? - ehsun7b
我在客户端使用Flex Mobile,并使用ActionScript进行编码。如果适合您,我可以将其提供给您(但对于我来说,这不是最佳解决方案,因为在移动设备上对ByteArray进行编码需要一段时间)。 - Zaur Guliyev
请将它发送给我(发送至 ehsunbehravesh dot com),这可能会给我一些想法。 - ehsun7b
JPEG格式有透明通道吗?A_RBG可能是问题所在。 - arynaq
4个回答

2

为什么不使用ByteArrayInputStreamImageIO一起使用?

您可以在API中找到有关ImageIO的更多信息。

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
    }
}

1
BufferedImage img = ImageIO.read(new ByteArrayInputStream(resimBytes)); 这段代码返回了一个空的img对象,导致了java.lang.IllegalArgumentException异常的出现!!! - Zaur Guliyev
我通过在Java中读取JPEG图像来创建了一个bytes,然后将该字节数组传递给这段代码。一切都运行正常。在Java的API中写道:“如果没有注册的ImageReader声称能够读取流,则返回null。”我建议您检查是否有任何可用的ImageReader,以及您的字节数组是否真的是JPEG图像。 - r0estir0bbe
哦,我明白了我的糊涂。我假设你的“byte”数组包含JPEG格式的数据。实际上,它是原始的颜色数据。抱歉。 - r0estir0bbe

0
你可以尝试用这个替换你的for循环:
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;
    }
}

可能会出现代码错误的问题:

  1. 通常你是逐行编写而不是逐列编写

  2. 你需要读取3个字节并构建一个int,而不是直接将字节写入像素(TYPE_INT_ARGB)

此链接解释了TYPE_INT_ARGB:TYPE_INT_RGB和TYPE_INT_ARGB的格式

希望这能有所帮助,不要太困惑 =)


0

bi.setRGB 接受一个4字节的“int”值,即ARGB 0xAARRGGBB。

然后你通过增加一个字节偏移计数器来递增,这样下一个像素将得到0xRRGGBBAA,然后是0xGGBBAARR等等。

假设你传递的byte[]是正确的4字节格式,你需要每次将“count”增加4,或者将传递的内容更改为int[](这实际上更正确,因为它确实包含int值)。


0

你好,我曾经面临同样的问题,当我将宽度和高度的值固定编码为(300,300)时,导致了类似的输出。然后我查阅了这个链接。 Raw byte[] to jpeg image 你可以忽略其中的位图部分。我猜想你也在硬编码宽度和高度值。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接