I'm saving a large PNG file (40000 x 3000) using PNGJ library. Now I need to rotate the image 90 degrees to the right without saving the whole image in memory. PNGJ library is limited to write images line by line, so I can't rotate each line and write the imagem column by column.
Is there any way to do that?
PNGJ library is limited to write images line by line
Actually, it's the PNG format that's line-oriented. And you can't read a single pixel of a PNG image without reading all the "previous" pixels. So, I guess you are out of luck.
The best you can do, I think, if you cannot store the full image in memory, is to load and write it by K horizontal stripes. You fill the first stripe by reading the full image (you only store the fist pixels of each row, that correspond to the pixels of the first horizontal stripe of the rotated image, discarding the rest), write it, and read again the file to fill and write the second stripe, etc.
This involves K readings of the original file (of course, you should make the stripe as thick as your memory permits, so as to make K small). I hope you get the idea.
You can do that with PNGJ.
Related
I have an image-only PDF file that looks like a scan of a really big page. Preview shows me that it is about 42x30 inches, and 3047x2160 pixelss. I guess it was scanned at 72dpi resolution.
I'm extracting this image with PDFBox by looking for instances of PDImageXObject, similar to https://stackoverflow.com/a/37664125/10026.
However, for this image, PDImageXObject.getWidth() and PDImageXObject.getHeight() give me 16928 and 12000, respectively. When I call PDImageXObject.getImage(), it creates an enormous BufferedImage in memory.
Is there a better way to get the image out of so that it keeps the original pixel size?
I am using the Jsteg method, but i have a confusion, something i don't quite understand.The steps are:
Get 8x8 pixel block
Discret cosine tranform
Quantization
Replace the Least Significant Bit
What i don't understand is, when i open the image in java using BufferedImage and ImageIO and do these steps, how do i save the changes? if i write:
ImageIO.write(img,"jpg",new_img);
does java recompress the image and then the hidden text is lost, or when it does the compression it doesn't change anything since i did compress manually?
or should i save it in another way?
Bottom line:After replacing LSB, how to save the encoded image ?
Currently we have a requirement where we have an image depicting the blueprint of the mall (red specifies the booked up areas and white specifies the available areas) and the image is available in a raster (JPEG) format.
We would like to drag and drop some icons onto the available areas of the image (in white). There should also be zoom in and zoom out functionality to be given for the above image as well
Since the JPEG has a lossy scaling, zooming after a certain limit can result in a jagged image. One proposed solution is to convert the image to SVG (Scalable Vector graphics).
Going with the expanded form of SVG, it simply tells us that image is:
s=>scalable (i.e. you can zoom to any level without compromising the quality)
v=>vectorized (i.e co-ordinates are available)
So by simply looking at the XML format of the image, we can predict whether to allow dropping an object at fill=red or fill=white where red and white are the two colors in the image. This might not be appropriate solution, but I'm just guessing it this way
Now the problems I see with this approach is:
Converting an image with some open source tool (InkSpace) - if we trace it with ink-space, which uses portace inside it to trace the image, it can handle only black and white colors.
Note-: Most of the tools comes with some license.
Problem with inkspace is that it embeds the image into the SVG map and does not create the co-ordinates. If you trace it with inkspace, it only creates the outline of the image.
Converting it with some online utility - Not recommended in our case, but doing so results in a large size of the SVG image. For a 700 KB file, the SVG generated is about 39 MB, which when opened up on a browser crashes the browser.
Most of the time when the image is converted to an SVG, it becomes way too large a big factor to worry about. There are utilities available like Gzip to compress files, but this is a two way route - first you convert, then you compress.
Using delinate (which employs a portace and autotrace engines in it) - the quality of the image produced is not good.
Using Java code - Again the quality suffers. Java graphics are not fully developed to handle the conversion (size is again way too large)
Converting the image to PDF, then to SVG - this also embeds the image into the SVG file, which is useless as no co-ordinates are available
Does anybody got any idea on this ,how to deal with this situation?,Can we handle the drag and drop on raster(jpeg,png...etc) images itself?
Thanks
Dishant Anand
This is a bit of a followup to my last question: Canvas is drawing too slowly
Now that I can draw images more quickly, the problem I am faced with is that the actual loading of the images takes far too long.
In the app I am working on, the user is able to play back video frames (jpegs) in succession, as though he is viewing the video in realtime. I have been using BitmapFactory.decodeFile() to load each jpeg in a Bitmap. I'm unable to load all images at once since there are about 240 of them, and that would use up all of my heap space. What I have been doing is preloading up to 6 at a time into an array by way of a separate thread in order to cut down on the time it takes for each image to display.
Unfortunately, it takes somewhere between 50 and 90ms to load an image, and I need to show an image every 42ms. Is there a faster way to load images possibly?
For clarification, these images are in a folder on the SD card, and they are all 720x480 jpegs. I am sampling them at half that size to cut down on memory usage.
I ended up doing this quite a bit differently than I had originally envisioned. There was quite a bit to it, but here's the gist of how I achieved my goal:
All images are stored on SD card and written to one file (each image takes up X bytes in the file)
Use native code to read from and write to the image file
When requesting an image, I pass the index of the image in the list and a bitmap object (RGB_565) to the native code using a JNI wrapper
The native code locks the bitmap surface, writes pixel data (as a uint8_t**) directly to the bitmap, then unlocks it
The image is rendered to the screen
By doing it this way, I only needed to store one image in memory at a time, and I was able to bypass garbage collection (since the bitmap was only created once and then repopulated natively). I hope someone else might find this strategy useful.
Guess you already tried all methods in this tutorial http://www.higherpass.com/Android/Tutorials/Working-With-Images-In-Android/2/ and chosen the fastest. Maybe tweaking resizing can decrease loading time.
Best of all would of course be if you didn't have to resize the images at all. If you have full control of the images maybe you could try to pack them as sprites, see article http://www.droidnova.com/2d-sprite-animation-in-android,471.html
I'm writing a basic sprite engine for my own amusement and to get better aquainted with Java's 2d API. Currently I am making use of large numbers of separate .png files with transparent backgrounds to represent the various sprites and different frames of animation that I need. Most 'real world' game development projects seem to make use of 'sprite sheets' which contain multiple sprites or frames of animation within a single file. Also, rather than making use of native image transparency support, people often nominate an arbitrary colour that does not appear in the sprite pallette to be the transparent colour. How does one manage a file like this programatically?
how do you know where one sprite
starts and the next begins
how do you deal with transparency
There may be other factors that I've not thought of here, so I may add to the list above as I think of things or as people make suggestions (please do so in the comments).
I currently use XML files generated by a simple sprite editor that store the sprite as a collection of (optionally animated) poses, which are in turn a collection of frames or cells. Frames store per-frame information like the x and y offset of the frame in sheet, cell width and height, and any transformation (resize/rotation/hue/etc.). Poses store individual frames and animation information (speed, for example), and a pose name to easily identify them in the program (hero.pose = sprite.pose["standing_right"]). Sprites serve as a document root to hold several poses, such as a pose for each facing direction.
A less flexible alternative I used earlier was to specify fixed sizes for cells and sheets and calculate frame offsets and sizes based on these values (e.g. width is always 32 pixels, so third sprite is at 32 * 2). Later I started specifying these dimensions in the file name (e.g. sprite_name_32x64.png) for sprites that don't fit the fixed cell dimensions. I like the new approach more, especially with a simplistic editor that fills most values for me and allows me to use sprites as templates for other sprites.
I use the alpha and transparency information stored in PNG images directly so I don't need to worry about storing it elsewhere, although other approaches would be to pick a fixed value per sprite and store somewhere, use the leftmost pixel in the pose if you know it's always empty, use a specific palette entry if you're using those, sprite masks, or what have you.
Not about java but generally you can make your all sprites in the same size. Thus, you will be able to generate your sprites in your game (or app) with a simple for loops.
But for different sized sprites there may be problem for spritesheet size (it can be larger than expected). So you must define an xml or json file for your spritesheet to find your sprite images in your code. You can use sprite sheet editors (there are plenty of them, I'm using Sprite Master) for quick and easy way to generate sprite sheet and coordinate datas.
Make your sprite sheet knowing the size and number of each sequence.
Grab a buffered image of your sheet and use something like this:
currentframe=spritesheet.getSubimage(x, y, w, h);
Your x and y will change based on the frame you are on. Keep the width and height the same to make things easy on yourself.
Forget trying to keep the entire game on one sheet. It's nuts and hard to manage. Use a new png for each animation sequence. If you are anal about saving space only create moving right animations and just flip the buffered image real time to move left.
Java will read png files with the alpha so don't worry about the transparency colour. Draw everything in pngs. Use Photoshop or Gimp.
Search google for java image TYPE_INT_ARGB
Well, since most of them are custom, those details are up to the implementor.
You'd generally have the file start with header information that contains the details of height/width and encoding, transparency, etc.
A lot of the time things are in one file because it is very expensive to open/read multiple files compared to open/read one file. Many game engines use zip or "ziplike" files with 0 compression to treat a single file as a filesystem.