-1

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

    }

}
Kammy
  • 409
  • 1
  • 7
  • 26

2 Answers2

1

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.

Community
  • 1
  • 1
Hendrik
  • 5,085
  • 24
  • 56
  • The last part about mime type is incorrect. It will not help using a URL, ImageIO does not use such mechanisms to recognize formats, it only interprets the stream contents. But it might actually fix the real problem, which is that ImageIO is only passed a part of the image content... – Harald K Dec 03 '13 at 18:51
  • Thanks @hendrik, marking this as answer as it helped me to solve problem. – Kammy Dec 10 '13 at 10:06
1

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.

Harald K
  • 26,314
  • 7
  • 65
  • 111
  • Right. I missed the part where you write to the OutputStream and then only read the last buffer. – Hendrik Dec 04 '13 at 07:55
  • yes above code is not as is. I modified it to post here. I was getting image with above servlet because of browser caching. – Kammy Dec 09 '13 at 10:01
  • Eh. Ok..? Your question states "Here is code [..]". If this is not the code that has the problem, you should update it with the shortest possible code that exposes your issue. Don't deliberately confuse people trying to help you... – Harald K Dec 09 '13 at 11:32
  • @haraldK sorry brother. I will update the code in question. Also I got the solution will post that too here. Thanks for your help. – Kammy Dec 09 '13 at 13:25