In a Java program you can store images like .png, .jpg and such in a BufferedImage. I don't think it works for animated gif images as it seems to lose its animation.
Currently I get normal images like:
BufferedImage image = ImageIO.read(new URL(images.get(x)));
String type = images.get(x).substring(images.get(x).length() - 3, images.get(x).length());
ImageIO.write(image, type, new File(title + "/" + filename));
Where images is a String[] of URLs.
As for gif's I'm getting them by:
byte[] b = new byte[1];
URL url = new URL(images.get(x));
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
DataInputStream di = new DataInputStream(urlConnection.getInputStream());
FileOutputStream fo = new FileOutputStream(title + "/" + filename);
while (-1 != di.read(b, 0, 1) && downloading)
fo.write(b, 0, 1);
di.close();
fo.close();
But I want to store them in the program and write them to a file another time. How do I store a GIF without writing it to a file but while keeping its animation?
If you are only interested in storing the gif in memory, and not in having it display from the java program. You could write the data you've received into a ByteArrayOutputStream rather than a FileOutputStream, and then take the resulting byte array and write that to a FileOutputStream at a later time.
If you would like to display the animated gif, you might want to check out the top answer in this post, although the first comment on the answer seems to be having a problem similar to yours.
Related
This question already has an answer here:
How to Merge Multiple MP4 Videos files in single file
(1 answer)
Closed 3 years ago.
Could someone please tell me what is wrong in the below code, I'm trying to merge two different video URLs to same file, (both videos have the same size 1024x720)
String url1 = "https://test.com/vid1";
String url2 = "https://test.com/vid2";
FileOutputStream out = new FileOutputStream(new File("test.mp4"));
writeToFile(url1, out);
writeToFile(url2, out);
out.close();
//Even tried the below way of first saving one file and then opening the same file to append the stream data
/*
FileOutputStream out = new FileOutputStream(new File("test.mp4"));
writeToFile(url1, out);
out.close();
out = new FileOutputStream(new File("test.mp4"), true);
writeToFile(url2, out);
out.close();
*/
void writeToFile(String url, FileOutputStream out) {
HttpsURLConnection con = (HttpsURLConnection) new URL(url).openConnection();
con.setRequestMethod("GET");
BufferedInputStream bis = new BufferedInputStream(con.getInputStream());
int count;
byte buf[] = new byte[20480];
while((count = bis.read(buf, 0, 20480)) != -1)
out.write(buf, 0, count);
bis.close();
con.disconnect();
}
I have tried to save the file using the above two methods but both create only one video file i.e., the second video is not appended (i'm able to save both files if given different names)
The problem is replacing the content of file and not concat.
the function FileOutputStream(File file, boolean append) use second parameter for this purpose. use this method with true value for the second parameter
To concatenate two videos you need special software. ffmpeg is one:
ffmpeg -i vid-1.mp4 -i vid-2.mp4 -filter_complex "[0:v:0][0:a:0][1:v:0][1:a:0]concat=n=2:v=1:a=1[v][a]" -map "[v]" -map "[a]" all.mp4
If you want to play the combined video. If you only need to store the info, your usual way should work.
This question already has answers here:
Can't read and write a TIFF image file using Java ImageIO standard library
(5 answers)
Closed 4 years ago.
I have some images stored in an oracle DB as blobs. I want to read them and display in a JLabel. After reading them, I have tried using ImageIO.read but it always returns null. See my code below:
Blob blob = rs.getBlob(2);
BufferedImage frontImg = ImageIO.read(blob.getBinaryStream());
lblFrontImage.setIcon(new ImageIcon(frontImg));
I am able to save the image to a file however using the following code so I know the image is valid:
Blob blob = rs.getBlob(2);
InputStream in = blob.getBinaryStream();
OutputStream out = new FileOutputStream("test.jpg");
byte[] buff = new byte[4096];
int len = 0;
while ((len = in.read(buff)) != -1) {
out.write(buff, 0, len);
}
out.close();
Other ways I have tried to display the image in a JLabel
byte[] frontBytes = rs.getBytes(2);
BufferedImage frontImg = ImageIO.read(new
ByteArrayInputStream(fileContent));
lblFrontImage.setIcon(new ImageIcon(frontImg));
And
byte[] frontBytes = rs.getBytes(2);
BufferedImage image;
ByteArrayInputStream bis = new ByteArrayInputStream(frontBytes);
image = ImageIO.read(bis);
bis.close();
lblFrontImage.setIcon(new ImageIcon(image));
Also
InputStream in = blob.getBinaryStream();
image = ImageIO.read(in);
byte[] frontImgBytes = blob.getBytes(1, (int) blob.length());
System.out.println("front bytes length: ====\n" + frontImgBytes.length);
BufferedImage frontImage = ImageIO.read(new
ByteArrayInputStream(frontImgBytes));
lblFrontImage.setIcon(new ImageIcon(frontImage));
Tried a lot of ways, just keep getting java.lang.NullPointerException. No other exception or error. Any help will be greatly appreciated.
I finally realised it was because the images were TIFF images. I couldn't use the default ImageIO libraries. I noticed another StackOverflow thread here Can't read and write a TIFF image file using Java ImageIO standard library and used your twelvemonkeys libraries #haraldK and it worked fine. Thanks a lot.
I want to use Gravatar but I don't want to publish users MD5 hashes of their e-mail addresses. And there is more potential problems. So I decided to download them and store them in my database.
But I have a problem with such a simple task as my profile picture (Earlybird) looks bad after downloading:
This is the code I used.
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
final URL url = new URL("http://www.gravatar.com/avatar/" + account.getGravatarHash() + "?d=identicon");
final BufferedImage image = ImageIO.read(url);
ImageIO.write(image, "jpg", baos);
pic = baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
Value in pic is then directly stored to the database. Other pictures in my database are stored fine so problem must be in these lines.
EDIT:
I just partially fix the problem by changing "jpg" for a "png" even thought Gravatar tutorial is mentioning "jpg". Also I don't want to specify image format (unless all Gravatars are png). Can I avoid that? I want just save the bytes I get.
Browsers in most cases work with raw bytes. However it is highly appreciated to send "Content-Type: image/..." header for each image.
When you save bytes in DB you also have to
either save image content type, provided by Gravatar for this image or
convert image into your default format, so you can to hardcode content type for all images from your DB
To get headers, provided by Gravatar, you can use Apache HTTP Client.
To convert image into your preferred format, you can use ImageIO.
I found one similar problem with working solution:
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()){
final URL url = new URL("http://www.gravatar.com/avatar/" + account.getGravatarHash() + "?d=identicon");
InputStream inputStream = url.openStream();
byte[] buffer = new byte[1024];
int n;
while (-1 != (n = inputStream.read(buffer))) {
baos.write(buffer, 0, n);
}
inputStream.close();
pic = baos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
Looks like this works with png and jpg Gravatars.
I am very new to image encoding and would rather not learn a whole lot about it. Basically I'm taking greyscale byte array where each byte equals one pixel. I'm getting this data from mnist where I get 28x28 byte images. Anyway, bellow is my code, so you understand what I'm trying to accomplish.
private def getImages = {
val filePath = getClass.getResource("/mnist/train-images.idx3-ubyte").getPath
val fis = new FileInputStream(filePath)
var bytes = new Array[Byte](4)
fis.read(bytes)
println((ByteBuffer.wrap(bytes).getInt()))
fis.read(bytes)
println((ByteBuffer.wrap(bytes).getInt()))
fis.read(bytes)
var rows = ByteBuffer.wrap(bytes).getInt()
println("Number of rows: " + rows)
fis.read(bytes)
var cols = ByteBuffer.wrap(bytes).getInt()
println("Number of cols: " + cols)
var imageBytes = new Array[Byte](rows * cols)
fis.read(imageBytes)
imageBytes.foreach(println(_))
// I created a byte array input stream to feed into ImageIO
// which should create my image
val b = new ByteArrayInputStream(imageBytes)
// This is where your helpful answer would be placed
// What is the code to encode this into jpeg, gif, or whatever?
// This returns null because I have not encoded the bytes
// in the proper format
val img = ImageIO.read(b)
// Errors out because img is null
ImageIO.write(img, "gif", new File("/home/dev/woot.gif"))
}
The format is just consecutive pixel bytes laid next to each other. My question is what Java library or function is available to convert these raw bytes into jpeg, gif, or whatever format I need?
Before you write it out with ImageIO, create a BufferedImage first. It can be as simple as using the setRGB methods, and has the added benefit of allowing you to observe the image before writing it out.
I have this following code in my servlet
response.setContentType("image/gif");
String filepath = "PATH//TO//GIF.gif";
OutputStream out = response.getOutputStream();
File f = new File(filepath);
BufferedImage bi = ImageIO.read(f);
ImageIO.write(bi, "gif", out);
out.close();
This code is just returning first frame of the image.
How to achieve returning full GIF image ?
Your GIF does not animate, because you are sending only the first frame to the client. :-)
Actually, you are, because ImageIO.read reads only the first frame (and a BufferedImage can only contain a single frame/image). You are then writing that single frame to the servlet output stream, and the result will not animate (it should be possible to create animating GIFs using ImageIO, but the code to do so will be quite verbose, see How to encode an animated GIF in Java, using ImageWriter and ImageIO? and Creating animated GIF with ImageIO?).
The good news is, the solution is both simple, and will save you CPU cycles. There's no need to involve ImageIO here, if you just want to send an animated GIF that you have stored on disk. The same technique can be used to send any binary content, really.
Instead, simply do:
response.setContentType("image/gif");
String filepath = "PATH//TO//GIF.gif";
OutputStream out = response.getOutputStream();
InputStream in = new FileInputStream(new File(filepath));
try {
FileUtils.copy(in, out);
finally {
in.close();
}
out.close();
FileUtils.copy can be implemented as:
public void copy(final InputStream in, final OutputStream out) {
byte[] buffer = new byte[1024];
int count;
while ((count = in.read(buffer)) != -1) {
out.write(buffer, 0, count);
}
// Flush out stream, to write any remaining buffered data
out.flush();
}