Java converting an image to an input stream WITHOUT creating a file - java

For an applet I'm working on I need to convert a BufferedImage file to an input stream so that I can upload the image to my MySQL server. Originally I was using this code:
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection connection =
DriverManager.getConnection(connectionURL, "user", "pass");
psmnt = connection.prepareStatement(
"insert into save_image(user, image) values(?,?)");
psmnt.setString(1, username);
ImageIO.write(image, "png", new File("C://image.png"));
File imageFile = new File("C://image.png");
FileInputStream fis = new FileInputStream(imageFile);
psmnt.setBinaryStream(2, (InputStream)fis, (fis.length()));
int s = psmnt.executeUpdate();
if(s > 0) {
System.out.println("done");
}
(while catching the relevant exceptions) The code hangs on the part where the applet attempts to save the image to the computer. The code worked perfectly in Eclipse or whenever I ran the applet from the localhost, so I'm assuming the problem is in the privileges that the applet has in saving files to the user's computer.
I was just was wondering if there was a way to turn the image file into an inputstream without having to save a file to the user's computer. I tried using:
ImageIO.createImageInputStream(image);
But then I couldn't convert the ImageInputStream back to an InputStream. Any Suggestions?
Thanks!

Typically you would use a ByteArrayOutputStream for that purpose. It acts as an in-memory stream.
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image,"png", os);
InputStream fis = new ByteArrayInputStream(os.toByteArray());

Have you tried writing to a ByteArrayOutputStream and then creating a ByteArrayInputStream from that data to read from? (Call toArray on the ByteArrayOutputStream and then call the constructor of ByteArrayInputStream which will wrap that byte array.)

Be careful using BytArray streams: if the image is large, that code will fail. i have not done much applet coding, but it's possible that the temp dir is available for writing (e.g. File.createTempFile() ).

Related

Export to Excel for absolute path

I'm trying to export a report to Excel. Using POI I'm able to store in to the path (say D:/reports) which I hardcoded in my code.
My requirement is, before the report generation, to ask for the path, the user wants to save the report to. How to achieve this?
You cannot store a file in user's computer without his permission/action.
1)Store your generated file in container (Tomcat's folder).
2)Write the file as response content.
3) Users get's a prompt to select the location to save the file to disk.
4) Delete the generated file after successfully writing to the user's computer.
you can't store the file in users computer.
Convert your workbook to byte array and write the file as response content.
Try the following:
// converting workbook to byte array
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] bytes = null;
try {
workbook.write(outStream);
bytes = outStream.toByteArray();
} finally {
outStream.close();
}
// setting file properties
response.setContentType('application/vnd.ms-excel');
response.setHeader("Content-disposition", "attachment;filename=excelname.xls");
// writing the byte[] to repsonse.
OutputStream out = response.getOutputStream();
out.write(bytes);
out.close();
By using the above code, you don't need save the file in tomcat and User gets a prompt to save the file in his location.

Exception on sending big files through java sockets

I'm creating a Chat in java for a university project, and one of the requirements is each user must have an image associate, this can be done through registration windows and data modification windows, in registration everything works great, but on the modification window, the program throws an exception when i try to send big files, both codes (registration and modification) are basiccally the same, changing only variables and path, but still gives my problem only in modification
Here is my code:
Client:
BufferedImage image = ImageIO.read(new File(usuario.getImagen().getCanonicalPath()));
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", byteArrayOutputStream);
byte[] size = ByteBuffer.allocate(4).putInt(byteArrayOutputStream.size()).array();
salida.write(size);
salida.write(byteArrayOutputStream.toByteArray());
salida.flush();
Server:
dir = new File ("." + "/Documentos/Imagenes de Verificacion/" +
usuarioRegistro.getNombreDeUsuario() + ".jpg");
sizeAr = new byte[4];
entrada.read(sizeAr);
size = ByteBuffer.wrap(sizeAr).asIntBuffer().get();
imageAr = new byte[size];
entrada.readFully(imageAr);
image = ImageIO.read(new ByteArrayInputStream(imageAr));
ImageIO.write(image, "jpg", new File(dir.getCanonicalPath()));
usuarioRegistro.setImagen(dir.getCanonicalFile());
And the exception is:
Exception in thread "Thread-0" 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.ucab.javachat.Servidor.model.ServidorModel.run(ServidorModel.java:198)
The line ServiorModel.java:198 is: ImageIO.write(image, "jpg", new File(dir.getCanonicalPath()));
In my tests i can send images of 20, 30, 80, 200 Kb, but when i try to send the 2.1mb file gives the error.
I think this i related with some data loose on the byteArray (maybe header data?) but what i dont know is how to fix it, my register window method uses the same sockets and OutputStream to send data and i succesfully send a 24mb image.
As per the documentation:
Returns a BufferedImage as the result of decoding a supplied File with
an ImageReader chosen automatically from among those currently
registered. The File is wrapped in an ImageInputStream. If no
registered ImageReader claims to be able to read the resulting stream,
null is returned. The current cache settings from getUseCacheand
getCacheDirectory will be used to control caching in the
ImageInputStream that is created.
Note that there is no read method that takes a filename as a String;
use this method instead after creating a File from the filename.
This method does not attempt to locate ImageReaders that can read
directly from a File; that may be accomplished using IIORegistry and
ImageReaderSpi.
Make sure you register an ImageReader or wrap your file on a FileInputStream, but since your implementation works I bet it's the image causing issues therefore,
Make sure that your image is of type: GIF, PNG, JPEG, BMP, and WBMP for these are the types supported by the class.

Downloaded zip file is invalid

I'm trying to download (and later extract) a zip file from my dropbox account using this code
URL url = new URL("-");
HttpsURLConnection con = (HttpsURLConnection) url.openConnection();
try (InputStream stream = con.getInputStream()) {
Files.copy(stream, Paths.get(parent.getAbsolutePath() + File.separator + "zippedCache.zip"));
}
The file I'm trying to download is a folder with another folder in it (empty). When I attempt to open the zipped folder, I get something along the lines of "cannot open the folder the compressed zipped folder is invalid" (translated using Google translator). When I unzip it, it's empty.
Can anyone explain what the problem here is?
Edit: Also, the zip folder is empty when I download it using Java, however downloading it normally through a web browser works fine.
Please verify your code again using a HttpURLConnection. This should work out.
For using Https you would need something like urlConnection.setSSLSocketFactory or similar.
You should try to read the InputStream in parts into a byte array and write into a FileOutputStream. It's simpler I think.
Example:
InputStream stream = con.getInputStream();
byte[] buffer = new byte[4096];
FileOutputStream out = new FileOutputStream("anything.zip");
while (stream.read(buffer) != -1) {
out.write(buffer);
}

ImageIO.read closes inputs stream

I write images and other data to binary file. When I read image via ImageIO.read(InputStream) from that file, it reads image, it is ok, but method closes given input stream and I cant proceed to read other data.
Why so it is made?
Then how read image without closing stream?
EDIT: It is simple code that writes image and string after into file:
File f = new File("test.bin");
if(f.exists())
f.delete();
f.createNewFile();
DataOutputStream os = new DataOutputStream(new FileOutputStream(f));
BufferedImage img = ImageIO.read(new File("test.jpg"));
ImageIO.write(img, "jpg", os);
os.writeUTF("test string after image");
os.close();
And code that reads all:
DataInputStream is = new DataInputStream(new FileInputStream(f));
BufferedImage img = ImageIO.read(is);
String s = is.readUTF(); // on this line EOFException occurs
System.out.println(s);
NetBeans output:
Exception in thread "main" java.io.EOFException
at java.io.DataInputStream.readUnsignedShort(DataInputStream.java:340)
at java.io.DataInputStream.readUTF(DataInputStream.java:589)
at java.io.DataInputStream.readUTF(DataInputStream.java:564)
at mediamanager.Main.test(Main.java:105)
at mediamanager.Main.main(Main.java:44)
May be I'm doing something wrong?
Quote from the documentation of ImageIO.read(InputStream)
This method does not close the provided InputStream after the read operation has completed; it is the responsibility of the caller to close the stream, if desired.
Emphasis not mine.
The problem is elsewhere. Probably in your code.
I can see two possible causes of such behaviour:
Image reader use buffer to read data from the stream to improve performance. So it reads more data from the stream.
Also image reader could try to read EXIF for already parsed image. Such information usually appended at the end of file to avoid full file rewriting when you are just adding a couple of piece of information about the image.
Try ImageIO.setUseCash(false) it could help.

Resources.openRawResource() issue Android

I have a database file in res/raw/ folder. I am calling Resources.openRawResource() with the file name as R.raw.FileName and I get an input stream, but I have an another database file in device, so to copy the contents of that db to the device db I use:
BufferedInputStream bi = new BufferedInputStream(is);
and FileOutputStream, but I get an exception that database file is corrupted. How can I proceed?
I try to read the file using File and FileInputStream and the path as /res/raw/fileName, but that also doesn't work.
Yes, you should be able to use openRawResource to copy a binary across from your raw resource folder to the device.
Based on the example code in the API demos (content/ReadAsset), you should be able to use a variation of the following code snippet to read the db file data.
InputStream ins = getResources().openRawResource(R.raw.my_db_file);
ByteArrayOutputStream outputStream=new ByteArrayOutputStream();
int size = 0;
// Read the entire resource into a local byte buffer.
byte[] buffer = new byte[1024];
while((size=ins.read(buffer,0,1024))>=0){
outputStream.write(buffer,0,size);
}
ins.close();
buffer=outputStream.toByteArray();
A copy of your file should now exist in buffer, so you can use a FileOutputStream to save the buffer to a new file.
FileOutputStream fos = new FileOutputStream("mycopy.db");
fos.write(buffer);
fos.close();
InputStream.available has severe limitations and should never be used to determine the length of the content available for streaming.
http://developer.android.com/reference/java/io/FileInputStream.html#available():
"[...]Returns an estimated number of bytes that can be read or skipped without blocking for more input. [...]Note that this method provides such a weak guarantee that it is not very useful in practice."
You have 3 solutions:
Go through the content twice, first just to compute content length, second to actually read the data
Since Android resources are prepared by you, the developer, hardcode its expected length
Put the file in the /asset directory and read it through AssetManager which gives you access to AssetFileDescriptor and its content length methods. This may however give you the UNKNOWN value for length, which isn't that useful.

Categories

Resources