Question

I want to invert image after image get streamed from given url in servlet, but its not working. But it giving me same image as it is when i send parameter invert=true in url to this servlet and giving me exception NullPointerException at below line.

for (int y = 0; y < bImageFromConvert.getHeight(); y++) {

Let me know where I am doing mistake. Please point me below is correct way to do invert thing, if not please show me way to make it work.

Here is code of servlet:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import org.apache.log4j.Logger;
import java.io.ByteArrayInputStream;

public class TestImage extends HttpServlet{

    /*
     *Initialize the Logger. 
     */
    private static Logger log = Logger.getLogger(TestImage.class);

    @Override
    public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{

        String imageURL="http://<host_name>/getimage"; //removed actual url
        String invert = request.getParameter("invert");
        InputStream resultInStream = null;
        //Gets the response's outputStream instance to write a image in the response.
        OutputStream resultOutStream = response.getOutputStream();

        try{
            //Initialize the URL for the requested image.
            URL imageUrl = new URL(imageURL);
            //opens the inputStream of the URL.
            resultInStream = imageUrl.openStream();
            //Initialize the byte array object to read and hold the bytes form the image URL stream.
            byte[] buffer = new byte[4096];
            int bytes_read;
            //writes the image bytes into the response's output stream.
            while((bytes_read=resultInStream.read(buffer)) != -1){
                resultOutStream.write(buffer, 0, bytes_read);
            }

            InputStream in = new ByteArrayInputStream(buffer);
            BufferedImage bImageFromConvert = ImageIO.read(in);

            /**
             * Code to invert image fetched from url 
             */
            if(invert != "true"){
                for (int x = 0; x < bImageFromConvert.getWidth(); x++) {
                    for (int y = 0; y < bImageFromConvert.getHeight(); y++) {
                        int rgba = bImageFromConvert.getRGB(x, y);
                        Color col = new Color(rgba, true);
                        col = new Color(255 - col.getRed(),
                                        255 - col.getGreen(),
                                        255 - col.getBlue());
                        bImageFromConvert.setRGB(x, y, col.getRGB());
                    }
                }
            }
            //Closing all the input and output streams.
            bImageFromConvert.flush();
            in.close();
            resultOutStream.close();
            resultInStream.close();
        } catch (Exception e) {         
            log.error("Unable to read and write the image",e);
        }

     }
}

[Solved] Fixed code:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import org.apache.log4j.Logger;
import java.io.ByteArrayInputStream;

public class TestImage extends HttpServlet {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    /*
     * Initialize the Logger.
     */
    private static Logger log = Logger.getLogger(TestImage.class);

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String imageURL="http://<host_name>/getimage"; //removed actual url
        // Sets the response content type to jpg image.
        String invert = request.getParameter("invert");

        InputStream resultInStream = null;
        // Gets the response's outputStream instance to write a image in the
        // response.
        OutputStream resultOutStream = response.getOutputStream();

        BufferedImage bImageFromConvert = null;

        try {
            // Initialize the URL for the requested image.
            URL imageUrl = new URL(imageURL);
            // opens the inputStream of the URL.

            if (object!=null && !object.equalsIgnoreCase(""))
            {
                resultInStream = imageUrl.openStream();

                if("true".equals(invert)){
                    /**
                     * Code to invert image fetched from url 
                     */
                    bImageFromConvert = ImageIO.read(resultInStream);
                    for (int x = 0; x < bImageFromConvert.getWidth(); x++) {
                        for (int y = 0; y < bImageFromConvert.getHeight(); y++) {
                            int rgba = bImageFromConvert.getRGB(x, y);
                            Color col = new Color(rgba, true);
                            col = new Color(255 - col.getRed(),
                                            255 - col.getGreen(),
                                            255 - col.getBlue());
                            bImageFromConvert.setRGB(x, y, col.getRGB());
                        }
                    }
                    ImageIO.write(bImageFromConvert, "JPG", resultOutStream); 
                }else{
                    // Initialize the byte array object to read and hold the bytes form
                    // the image URL stream.
                    byte[] buffer = new byte[4096];
                    int bytes_read;
                    // writes the image bytes into the response's output stream.
                    while ((bytes_read = resultInStream.read(buffer)) != -1) {
                        resultOutStream.write(buffer, 0, bytes_read);
                    }
                }
                // Closing all the input and output streams.
            }
            resultOutStream.flush();

        } catch (Exception e) {
            log.error("Unable to read and write the image", e);
        } finally {
            if (resultOutStream != null) {
                try {
                    resultOutStream.close();
                } catch (Exception ignore) {
                }
            }
            if (resultInStream != null) {
                try {
                    resultInStream.close();
                } catch (Exception ignore) {
                }
            }
        }

    }

}
Was it helpful?

Solution

you are dealing with two problems:

  1. When writing invert != "true" you are comparing for object identity, not equality. To fix this, write !"true".equals(invert). See e.g. here for more details.
  2. In your case ImageIO.read(in);, apparently returns null. According to the documentation this happens...

If no registered ImageReader claims to be able to read the resulting stream, null is returned.

So it seems, that ImageIO simply can't read the format you are throwing at it. You might be able to help ImageIO, by handing it the URL, and not the InputStream: ImageIO.read(imageUrl) — that way, ImageIO might be able to guess the format through the file extension or the mime type (just speculation). But in any case, this would also save you some effort.

Good luck.

OTHER TIPS

Your stream copying code is bogus.

You are copying the original contents of the URL imageURL correctly to the ServletOutputStream (even if I don't think that is what you intend to do) but then you create a ByteArrayInputStream based on buffer, which will hold at most the 4096 last bytes of the image... ImageIO won't recognize this (unless there is a very small image, that is read in a single chunk).

So, do as @hendrik says, just pass the URL to ImageIO. And then write the inverted image to the ServletOutputStream.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top