GIF file encoding to save and display in browser

E

Edward

I have a simple servlet that reads a GIF from local machine and then
saves this file and displays the image in the browser. My problem is
that the image gets corrupted somehow. Looking at the file in Notepad
I see that the bytes are slightly different (resulting in a much
different image). I get a similar problem loading a JPEG but BMP looks
unchanged. I suspect that there is something I need to do with the
encoding but I am clueless in this regard. I think that perhaps
something needs to be done with the line:

InputStreamReader isr = new InputStreamReader(fis,"windows-1252");

but I have been unable to find any decent web resouce talking about
encoding a GIF. Or perhaps I am way off base and that I why I defer to
the local wisdom in the NG!

The servlet in its entirety:

package testPkg;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class OutImage extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {

FileInputStream fis = new FileInputStream("C:\\test.gif");
InputStreamReader isr = new InputStreamReader(fis,"windows-1252");
Reader in = new BufferedReader(isr);
int ch;
StringBuffer buffer = new StringBuffer();
while ((ch = in.read()) > -1) {
buffer.append((char) ch);
}
in.close();
String s = buffer.toString();
File outputFile = new File("C:\\testOUT.gif");
FileOutputStream fo = new FileOutputStream(outputFile);
fo.write(s.getBytes());
fo.close();
ServletOutputStream sos = response.getOutputStream();
sos.write(s.getBytes());
}
}
 
M

Matt Humphrey

Edward said:
I have a simple servlet that reads a GIF from local machine and then
saves this file and displays the image in the browser. My problem is
that the image gets corrupted somehow. Looking at the file in Notepad
I see that the bytes are slightly different (resulting in a much
different image). I get a similar problem loading a JPEG but BMP looks
unchanged. I suspect that there is something I need to do with the
encoding but I am clueless in this regard. I think that perhaps
something needs to be done with the line:

InputStreamReader isr = new InputStreamReader(fis,"windows-1252");

but I have been unable to find any decent web resouce talking about
encoding a GIF. Or perhaps I am way off base and that I why I defer to
the local wisdom in the NG!

You are badly mixing byte and character data. GIFs are interpreted as
bytes. To do a simple copy try something like:

FileInputStream fis = new FileInputStream("C:\\test.gif");
FileOutputStream fos = new FileOutputStream ("C:\\testOUT.gif:");
byte [] buffer = new byte [1024];
int len = 0;
while ( (len = fis.read(buffer)) >= 0 ) {
fos.write(buffer, 0, len);
}

And don't forget to set the content header.

Alternatively, if all this function does is just serve up images from files,
let the web server do it--it's usually better optimized for that kind of
thing. Just place the files in a directory where the web server can find
them.

Cheers,
Matt Humphrey (e-mail address removed) http://www.iviz.com/
 
J

James Westby

Edward said:
I have a simple servlet that reads a GIF from local machine and then
saves this file and displays the image in the browser. My problem is
that the image gets corrupted somehow. Looking at the file in Notepad
I see that the bytes are slightly different (resulting in a much
different image). I get a similar problem loading a JPEG but BMP looks
unchanged. I suspect that there is something I need to do with the
encoding but I am clueless in this regard. I think that perhaps
something needs to be done with the line:

InputStreamReader isr = new InputStreamReader(fis,"windows-1252");

but I have been unable to find any decent web resouce talking about
encoding a GIF. Or perhaps I am way off base and that I why I defer to
the local wisdom in the NG!
[snip]

From the Javadoc for InputStreamReader

http://java.sun.com/j2se/1.4.2/docs/api/java/io/InputStreamReader.html

An InputStreamReader is a bridge from byte streams to character streams:
It reads bytes and decodes them into characters using a specified charset.



A .gif image does not contain characters, and if you read it as
characters, and convert them from a charset the content will be changed.
This is the behaviour that you are seeing.



From the Javadoc for FileInputStream

http://java.sun.com/j2se/1.4.2/docs/api/java/io/FileInputStream.html

FileInputStream is meant for reading streams of raw bytes such as image
data.


I suggest that you use the FileInputStream itself, rather than wrapping
it in an InputStreamReader

Check out the method read(byte[] b).


James
 
T

Thomas Hawtin

Edward said:
I have a simple servlet that reads a GIF from local machine and then
saves this file and displays the image in the browser. My problem is
that the image gets corrupted somehow. Looking at the file in Notepad
I see that the bytes are slightly different (resulting in a much
different image). [...]
public void doGet(HttpServletRequest request, HttpServletResponse
response)
throws ServletException, IOException {

FileInputStream fis = new FileInputStream("C:\\test.gif");

You should close this stream, even if an exception occurs. So add a try
{ here, and } finally { close(); } when you have finished with it.
InputStreamReader isr = new InputStreamReader(fis,"windows-1252");
Reader in = new BufferedReader(isr);
int ch;
StringBuffer buffer = new StringBuffer();

It's a binary file, so don't tread it like character data. Delete all
the character stuff. You could copy it into a ByteArrayOutputStream, or
just straight into the response output stream.
while ((ch = in.read()) > -1) {
buffer.append((char) ch);
}
in.close();
String s = buffer.toString();
File outputFile = new File("C:\\testOUT.gif");
FileOutputStream fo = new FileOutputStream(outputFile);
fo.write(s.getBytes());
fo.close();

You should set the MIME type before sending the data.
ServletOutputStream sos = response.getOutputStream();
sos.write(s.getBytes());
}

Tom Hawtin
 
E

Edward

Matt said:
Edward said:
I have a simple servlet that reads a GIF from local machine and then
saves this file and displays the image in the browser. My problem is
that the image gets corrupted somehow. Looking at the file in Notepad
I see that the bytes are slightly different (resulting in a much
different image). I get a similar problem loading a JPEG but BMP looks
unchanged. I suspect that there is something I need to do with the
encoding but I am clueless in this regard. I think that perhaps
something needs to be done with the line:

InputStreamReader isr = new InputStreamReader(fis,"windows-1252");

but I have been unable to find any decent web resouce talking about
encoding a GIF. Or perhaps I am way off base and that I why I defer to
the local wisdom in the NG!

You are badly mixing byte and character data. GIFs are interpreted as
bytes. To do a simple copy try something like:

FileInputStream fis = new FileInputStream("C:\\test.gif");
FileOutputStream fos = new FileOutputStream ("C:\\testOUT.gif:");
byte [] buffer = new byte [1024];
int len = 0;
while ( (len = fis.read(buffer)) >= 0 ) {
fos.write(buffer, 0, len);
}

And don't forget to set the content header.

Alternatively, if all this function does is just serve up images from files,
let the web server do it--it's usually better optimized for that kind of
thing. Just place the files in a directory where the web server can find
them.

Cheers,
Matt Humphrey (e-mail address removed) http://www.iviz.com/

That did the trick!

I realize that it would be simpler just to load the image with the <img
src="C:\temp.gif"> type tag but I am trying to educate myself. I am
also trying to solve a much more complex problem and I am hoping that
learning more about streams of binary data will help me solve the
problem or at least learn enough about the problem to ask an
intelligent question.

Thanks!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,012
Latest member
RoxanneDzm

Latest Threads

Top