At present I am rendering a DAE using a c++ based graphics engine, and programmatically taking a screenshot to get the PNG image as if the camera is viewing from above (looking directly down). This is quite tedious.
Since I do not need to actually look at the models on screen, is it possible to do the same programmatically without rendering using java ?
At present, it is easy to convert between other 2d formats such as PNG to jpeg using buffered image:
BufferedImage newImage = new BufferedImage( pngImage.getWidth(), pngImage.getHeight(), BufferedImage.TYPE_INT_RGB);
newImage.createGraphics().drawImage( pngImage, 0, 0, Color.BLACK, null);
Is there a similar way to load the DAE and take the equivalent of a screenshot by specifying the camera position, angle and distance as input coordinates ?
Related
I am trying to write some programs where I load images to a panel.
Here are my 5 questions:
1> Is there any restriction on what kind(extension) of images can be loaded? I tried to load a .bmp file, it didn't load even after I renamed it with .jpg. However, some other file that were with extensions such as .png or .jpg loaded.
2>Is there a way I can cut an image through java to create a new image. Say, I have a 600x600 pixel image and I want to create a new image by selecting a 200x200 pixel from the middle of the original picture.
3>Is there a way I can resize an image?
4>Can I add an image to a scrollpane?
5> Can I rotate an image by an angle ,say 30 degree?
That's it. A little elaboration with examples will be nice. Thanks in advance.
1> Is there any restriction on what kind(extension) of images can be
loaded? I tried to load a .bmp file, it didn't load even after I
renamed it with .jpg. However, some other file that were with
extensions such as .png or .jpg loaded.
Image I/O has built-in support for GIF, PNG, JPEG, BMP, and WBMP. Image I/O is also extensible so that developers or administrators can "plug-in" support for additional formats. For example, plug-ins for TIFF and JPEG 2000 are separately available.
Check the Reading/Loading an image tutorial page
2>Is there a way I can cut an image through java to create a new
image. Say, I have a 600x600 pixel image and I want to create a new
image by selecting a 200x200 pixel from the middle of the original
picture.
Two ways. Croping the image using Clipping with Graphics. But faster approach is to use BufferedImage.getSubimage(int x, int y, int w, int h) method.
BufferedImage image = ImageIO.read("image file");
image = image.getSubimage(50, 50, 200, 200);
This will crop an image at location(x, y) == (50, 50) and size 200 x 200.
3>Is there a way I can resize an image?
The discussion about the various approach will take a size of a blog. Read through the The Perils of Image.getScaledInstance() article for good insight.
However, a quick approach for example: with cWidth and cHeight
BufferedImage tmpImage = new BufferedImage(cWidth, cHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = (Graphics2D)tmpImage.getGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.drawImage(image, 0, 0, cWidth, cHeight, null);
There is working example done by MadProgrammer. It is also better to use external library such as this which does this works nicely.
4>Can I add an image to a scrollpane?
Direct adding is not suggested. use JLabel instead. Or use a custom component and override the paintComponent(Graphics g) function and draw inside it. There are some working example with these two approach. Generally working with JLabel is easier.
See this question answers. Mine including #MadProgrammer. And The custom painting official tutorial page.
5> Can I rotate an image by an angle ,say 30 degree?
Yes using the Graphics2D.rotate(double theta) function; There are actually much more things you can do with the Graphics2D API. Working examples are shown by MadProgrammer here and here.
I am trying to make some kind of map maker, using the old 2D style of games such as Final Fantasy 4. Basically they had everything set up in a grid where each square on the grid might have taken 16x16 or 32x32 pixels.
I would like to start out small, and get the main things down first. Such as generating a map which could be, say, 128x128. This means, that I should be able to feed the program an array of numbers representing the different tiles available, and then the program should make a new picture by placing the tiles as the array specifies (So the one in Index 0 will be placed at 0,0 etc).
I plan to show the picture when I am done, but that should be easy as pie.
I've been looking around for a solution and all I could find was merging pictures on top of each other (as in layers on top of each other), rather than side by side, so can any one point me in the right direction? I'd like it if I didn't have to rely on 3rd party libraries, as this is more of a learning experience than practical application :)
First, create the output BufferedImage to be the size you need.
BufferedImage image = new BufferedImage(width, height, imageType);
Then, get the Graphics2D object from the image and start drawing the smaller image in the places they need to be in the resulting image:
Graphics2D g2 = image.createGraphics();
for (BufferedImage img : images) {
g2.drawImage(img, x, y, null);
}
Then, you can save the image to the desired format: jpg, png or gif.
ImageIO.write(image, "jpg", file);
I want to load some images to the cloud, but I want to add some protections when someone views the photos and saves the images; they will not see anything because of the transparency.
would the code be common for Java and Android? I would like to prototype it in Java first.
I have found some code that combines two files. One file is my main file the other is a transparent file. The combined file does not have a transparent overlay.
Do I need to use an image drawing order?
http://www.developer.nokia.com/document/Java_Developers_Library_v2/GUID-D3E35E6F-0C45-48ED-B09D-F716E14C1C02/javax/microedition/amms/control/imageeffect/OverlayControl.html
BufferedImage image = ImageIO.read(new File("rose.jpg"));
BufferedImage overlay = ImageIO.read(new File("myimg1.gif"));
// create the new image, canvas size is the max. of both image sizes
int w = Math.max(image.getWidth(), overlay.getWidth());
int h = Math.max(image.getHeight(), overlay.getHeight());
BufferedImage combined = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
// paint both images, preserving the alpha channels
Graphics g = combined.getGraphics();
g.drawImage(image, 0, 0, null);
g.drawImage(overlay, 0, 0, null);
// Save as new image
ImageIO.write(combined, "PNG", new File("combined.png"));
This won't work. If they can see the image, they can copy it, one way or another. A solution to consider is providing watermarked thumbnails at no charge, then only offering the full resolution image for a fee. However, they can still copy the full resolution image once they pay.
You can actually put a trans image as an overlay to the orginial image, that will
Protect from download, I think this is usually done by the server side aka your cloud
I know from some websites that they use some kind of an overlay such as yours
And the browser can't see the image below so you can't download.
I actually didn't understand how you implementing this - the image is opened in the browser?
Just a wild though, you can also cut the image into pieces like a jigsaw puzzle
The device won't have problems connecting it togther but when you download you'll
Download only "one piece of the puzzle" :-P
I'm trying to read, rescale and save images within a Servlet. That's the relevant code:
BufferedImage image = ImageIO.read(file);
BufferedImage after = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
AffineTransform at = AffineTransform.getScaleInstance(factor, factor);
AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
after = scaleOp.filter(image, null);
ImageIO.write(after, "JPG", file));
The original file is a plain RGB-Jpeg, but when I open and save the file it comes out as a CMYK-Jpeg. That happens even if i don't rescale the image, just opening and closing the image causes the problem.
When I open PNGs or GIFs everything is fine. Does anybody know what to do here? I would expect ImageIO's read-Method to retain the original colorspace.
If there's another way comfortable way of reading jpeg's?
Thanks for any suggestions!
You create after and then overwrite it with scaleOp.filter. Is this correct? So your after image may not be RGB even though you think it is? If you want after to be RGB then you may need to 'draw' image onto after before you do the transform.
I have had the same problem, and found this page.
I tried the suggestion above of creating a BufferedImage with the right type and using it as the after image instead of null in the filter call; and that did indeed resolve the problem.
ImageIO.read ignores all embedded metadata, including an embedded color profile, which defines how RBG values map to physical devices such as screens or printers.
You could read the metadata separately and pass it to ImageIO.write, but it's easier to just convert the image to the (default) sRGB color space and ignore the metadata.
If you don't mind losing the metadata, replace
after = scaleOp.filter(image, null);
with
after = scaleOp.filter(image, after);
From the documentation of AffineTransformOp.filter:
If the color models for the two images do not match, a color conversion
into the destination color model is performed.
I am trying to load a PNG image using the javax.imageio.ImageIO.read() method. However, I want the resulting type to be "BufferedImage.TYPE_4BYTE_ABGR", but it ends up as an indexed image ("BufferedImage.TYPE_BYTE_INDEXED"). Is there any way to load an image as unindexed, when the original image is indexed? There are about 120 images, so it would take too long to make them all unindexed by hand.
If you're not opposed to using JAI, you can create a rendering chain for the RenderedImage (BufferedImage implements the interface) and add a format operation to the chain:
JAI.create("format",...) operation with a rendering hint with a key of JAI.KEY_REPLACE_INDEX_COLOR_MODEL.
A pure-ImageIO approach would be to create a new BufferedImage of the type you want and draw the one loaded from ImageIO.read into the new BufferedImage:
BufferedImage image = ImageIO.read(inputFile);
BufferedImage convertedImage = new BufferedImage(image.getWidth(),
image.getHeight(), BufferedImage.TYPE_4BYTE_ABRG);
convertedImage.createGraphics().drawRenderedImage(image, null);