I'm developing AppEngine application. One of it's features is splitting an animated .gif image into separate frames. I've searched a lot to find the way how to do it and finally found the solution. Unfortunately the solution is based on ImageReader and I cant use it on the server, because:
javax.imageio.ImageReader is not supported by Google App Engine's Java
runtime environment
Are there any other ways to decode GIF-image without this class?
First some thing about frame itself. There are two implications about splitting an animated .gif image into separate frames. 1) Literally, a frame is a frame in the sense of an animated GIF. The problem is frames which constitute an animated GIF image are related. The disposal method of an animated GIF dictates what to do with the previous frame when drawing the current frame. You can override it; fill with background color before drawing the new frame, or you can do whatever you think appropriate before drawing the new frame. If you think the above situation is complicated, what about transparency of frames? logical position to draw each frames?
If we go along this road, there is no need to use a dedicated ImageReader, just read relevant parts of the image and copy each frame data, save it along with a header and color palette. The consequence is: the resulting image might look weird and meaningless. Look at the example below:
The first frame
The second frame
And the original
You can see the second frame doesn't look so good. The truth is, the second frame is a transparent one which build on top of the first frame (this animated GIF only contains 2 frames). You are expect to see through the second frame and altogether, they make an animation.
Now let's see what the second implication of splitting an animated .gif image into separate frames. 2) In this case, the frame is a actually is a composite which builds upon the previous frames and which is what we are seeing when viewing an animated GIF. In order to achieve this, we have to take into effect the history of the frame loop, the logical position of each frame, and the transparency of the frames themselves.
Let's see what we get now:
The first frame
The second frame
Now the first frame is the same as in the first situation, but the second frame is constructed on top of the first one and it's not transparent anymore.
In the second case, we do have to decode and encode the frames to achieve the desired result. Besides looking nice, another good thing about this is you can save the resulting images in any format the encoder support.
The examples in this post are generated by the GIF related part of iCafe
Related
Is there a FFMPEG command, where if we pass a video file, on every scene changes it should produce a keyframe for it. And Keyframe to my understanding is a series of files(image or video) files for an video, which can be used for playing on hover of the video. Kindly let know if we can do this?
Is there a FFMPEG command, where if we pass a video file, on every
scene changes it should produce a keyframe for it.
Well, It depends on what codec, and what you are calling a scene. x264 has the scenecut parameter for adjusting scene sensitivity. However, what x264 calls a scene, may not be the same thing you call a scene.
A Michael bay movies for example has a hard cut every 4 or 5 seconds. x264 may consider every "cut" a scene. Anything more clever than a cut, or a fade, ffmpeg will not handle.
And Keyframe to my understanding is a series of files(image or video)
files for an video, which can be used for playing on hover of the
video. Kindly let know if we can do this?
No, not at all.
A key frame is a single frame, not a series of frames or files. It also has nothing to do with "hover". A keyframe is just an independent frame, meaning you can decode it independently without first having to decode any frames that it may reference.
Video compression does not just encode every frame. It will encode a frame, then for the next frame, encode only the parts that changed. This is called a "predicted frame" and it is not decodable without decoding the referenced frame. A key frame is just a frame that does not reference any other frames.
Sometimes some players may make optimizations where it will preview keyframes on hover because keyframes are faster to decode than predicted frames. But this is 100% a player optimization and not all plays do it.
To me, thed sounds line an xyproblem.
I have a very large complicated diagram that needs to be drawn on the fly.
I am already using a double buffered technique to paint the image (from this answer: Using threads to paint panel in java) however, the generated image that is being painted is so large that it cant be painted as a single image (and the multiple images required to paint it cant be stored in memory all at the same time). For this reason, I paint the currently visible area of the view + some margin. As I scroll, I paint the area that is going to come next, and remove from memory the area we just came from. However, if the user then decides to change direction, they need to wait for this area to be painted again. My question is this:
If a single "frame" of the screen being painted is approximately 1000*1000 pixels, in which approximately 5000 lines/circles are drawn (nodes/edges of a graph) is it likely to be more efficient to repaint this image each time, or is there a way to affectively cache the image to hard disk (to avoid java heap limitations).
Ive already optimised the paint method as much as I can think of, but there are still several seconds of delay if a user scrolls to quickly (i.e. moves out of the painted area before the next set of "frames" are painted). So my second question is this: Will moving to OpenGL offer a large improvement, and will it require major changes to the infrastructure of the code? (I tried doing this a couple of days ago, and found it was not as simple as I thought - often led to the computer crashing).
Several things come to mind:
Profile to verify your working hypotheses; self-time the animation budget on your target platform for comparison, as shown in this AnimationTest.
Compare your approach to the example cited here; it scales into the 1000's and accommodates dragging selections into the hundreds.
If your frames have a suitable geometry, consider adopting the flyweight pattern for rendering; JTable rendering is an example; the underlying mechanism using CellRendererPane is examined here.
I'm looking for a function that could process animated gif image to write text on top of it.
The working solution is probably provided by Gif4j lib, but I'm looking for open-source solution or advice how to implement it on my own.
How can I put text on a gif and save it as a new gif in Java?
You need to:
Split the animation into separate frames.
Write the text on each frame. For examples see answers like these (the first is more closely related, but the second source does the same, and is simpler).
Java Text on Image
How to resize text 1
Construct the frames into a new animated GIF. See Create animated GIF using imageio at the OTN, where I discuss the code used in a GIF animation tool.
I'm currently working in a map editor for a 2D, tile based game. When I create a new map, the tileset is loaded into memory and displayed in a JPanel that's inside a JScrollPane, so I can choose the tiles I wish to draw.
At first, I was just drawing the full image, but that made scrolling pretty slow, so now I only draw the visible portion of it and that works just fine. What I'm worried about is the memory usage, because the tileset is pretty big. I'm not getting any OutOfMemory erros, but I would like to optimise everything I can.
I tried using ImageReader together with ImageReadParam.setSourceRegion(); and that uses a lot less memory, but the scrolling becomes slower and the image blinks like crazy when scrolling - probably because it takes some time to read the image form disk.
So, is there a good way to quickly load parts of a big image without fully loading it? Or maybe there's a way to fully load it but in a compressed manner?
I would like to control the speed of an animated GIF in a Java applet. Is there a way to do this? If not, is there a way to access the data of an animated GIF so the applet can draw the animation image by image on its own?
I think that the frame rate is embedded into the GIF. You could somehow extract the images from the GIF, but that's harder than starting with the individual images and animating them in JS, which is harder than recreating the GIF with your preferred frame rate.
If you're going to use the GIF only once and the frame rate isn't going to change, just recreate the GIF. If you need to change the speed based on inputs from your applet, you could use the approach here. It alternates between two gifs, but there's nothing stopping you from loading in PNGs and alternating through an Array of those.
The animated GIF format is consists of data for each frame along with a delay value (how long to show that frame). The delay is separate for each frame, and is stored as two bytes and measures as hundred's of a second.
Netscape (back when it was the web), couldn't show the frames faster than 10 per second. So lots of tools just said screw it, and set delay for all the frames to 0. Lots of old gifs and old tools, have keep these screwed up frame delay times around.
With faster computers and browsers, they worked around this by checking if any of the frames had a delay <= 50ms (20+ fps). IF they did, the delay was increased to 100ms (10fps).
In principle, the best solution would be to just fix the GIF you're using to have accurate frame delays in them. If that isn't viable, use that same old workaround. Break the frames out of the animated GIF and do the animation yourself, defaults to a 100ms delay if the specified delay is <= 50ms. This will give you the same behavior as what you see in most web browsers.
Read about this a while ago. Think most of the details on mentioned on wikipedia (including the animated GIF format and the per frame delays). If it you really want some solid references, I can dig them for you.