简体   繁体   中英

Error while converting image to byte[] in Java using WritableRaster and DataBufferByte.

I am trying to convert image to byte[] using code

public static byte[] extractBytes(String ImageName) throws IOException {
    // open image
    File imgPath = new File(ImageName);
    BufferedImage bufferedImage = ImageIO.read(imgPath);

    // get DataBufferBytes from Raster
    WritableRaster raster = bufferedImage.getRaster();
    DataBufferByte data = (DataBufferByte) raster.getDataBuffer();

    return (data.getData());
}

When I am testing it using code

public static void main(String[] args) throws IOException {

    String filepath = "image_old.jpg";
    byte[] data = extractBytes(filepath);
    System.out.println(data.length);
    BufferedImage img = ImageIO.read(new ByteArrayInputStream(data));
    File outputfile = new File("image_new.jpg");
    ImageIO.write(img, "jpeg", outputfile);
}

I am getting data.length = 4665600 and getting error

Exception in thread "main" java.lang.IllegalArgumentException: image == null!
    at javax.imageio.ImageTypeSpecifier.createFromRenderedImage(ImageTypeSpecifier.java:925)
    at javax.imageio.ImageIO.getWriter(ImageIO.java:1591)
    at javax.imageio.ImageIO.write(ImageIO.java:1520)
    at com.medianet.hello.HbaseUtil.main(HbaseUtil.java:138)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)

But when I am changing my extractBytes code to

public static byte[] extractBytes (String ImageName) throws IOException {

   ByteArrayOutputStream baos=new ByteArrayOutputStream();
        BufferedImage img=ImageIO.read(new File(ImageName));
        ImageIO.write(img, "jpg", baos);
        baos.flush();

        return baos.toByteArray();
    }

I am getting data.length = 120905 and getting success(image.jpg getting created in the desired location)

The thing is, the first version of extractBytes reads an image, and just returns the image's pixels as an array of bytes (assuming it uses DataBufferByte ). These bytes are not in a file format, and are useless without extra information, such as width, height, color space etc. ImageIO can't read these bytes back, and because of this, null is returned (and assigned to img , later causing an IllegalArgumentException from ImageIO.write(...) ).

The second version decodes the image, then encodes it again in JPEG format. This is a format ImageIO will be able to read, and you get an image (assigned to img ) as you expect.

However, you code seems like just a very, very CPU-expensive way of copying images (you decode an image, then encode, then decode again, before finally encoding)... For JPEG files this decode/encode cycle will also degrade the image quality. Unless you are planning to use the image data for anything, and just want to copy an image from one place to another, don't use ImageIO and BufferedImage s. These types are intended for image manipulation.

Here's a modified version of your main method:

public static void main(String[] args) throws IOException {
    byte[] buffer = new byte[1024];

    File inFile = new File("image_old.jpg");
    File outFile = new File("image_new.jpg");

    InputStream in = new FileInputStream(inFile);
    try {
        OutputStream out = new FileOutputStream(outFile);

        try {
            int len;
            while ((len = in.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
        }
        finally {
            out.close();
        }
    }
    finally {
        in.close();
    }
}

(It's possible to write this better/more elegant using try-with-resources in Java 7, or NIO2 Files.copy in Java 8, but I leave that to you. :-) )

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