How to make a BufferedImage work with this image? (java) - java

I've got this picture:
Imagine this as a 4x4 tile world of which the tiles are 32x32 pixels each.
then take a look at picture:
Look at the stone tile, it has edges which are outside the grid. Can I use a bufferedImage for this or do I need to do something else to make this work?
If so, could you help me with it by explain it because I've got no clue on how to achieve this is my game?
another example picture:
Let me explain it More Clearly... 1st image = Grid, 2nd Image = Tile Overlapping the grid... (thats what i want to have because then it's a new tile which I can use to make my game look better!), 3d Image = An example of how it would tile!

To completely eliminate boundary artifact, you can use Penrose tiles.
You can mitigate the edge artifact using anti-aliasing. This example uses TexturePaint with three variant shades of each color: original, darker and lighter. You can experiment with a larger number of shades for better results.

Simply use PhotoShop to edit the image to 32x32 pixel size....then use it in your game....
/////////////EDITED//////////////////
As shown here, AffineTransformOp offers the additional flexibility of choosing the interpolation type.
BufferedImage before = getBufferedImage(encoded);
int w = before.getWidth();
int h = before.getHeight();
BufferedImage after = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
AffineTransform at = new AffineTransform();
at.scale(2.0, 2.0);
AffineTransformOp scaleOp =
new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
after = scaleOp.filter(before, after);

Related

Java rotated buffered image gets cut off

Firstly, I am trying to make a simple game in Java. I have a viewport that shows a tile map and I have a tank in the middle that moves by controlling the JScrollBars of the scrollpane in which the viewport resides in. So far everything has been going well, until I needed to rotate an image. Here is a picture of the game: Note: the tank body and tilemap are on seperate panels and do not share the same graphics.
Picture of non rotated tank body:
Essentially, I want to rotate a buffered image around its center (rotating in place) using arrow keys. I already have the code for the keys, and I also have a method to try and rotate the buffered image given a buffered image and angle in degrees (the angle is changed to radians in the method). This method will return a buffered image that is rotated correctly. Here is the code:
public static BufferedImage rotateImage(BufferedImage image, double angle) {
if(angle == 0)
return image;
else {
angle = Math.toRadians(angle);
double x = Math.abs(Math.cos(angle));
double y = Math.abs(Math.sin(angle));
int newWidth = (int) Math.floor(image.getWidth()*x + image.getHeight()*y);
int newHeight = (int) Math.floor(image.getHeight()*x + image.getWidth()*y);
BufferedImage rotated = new BufferedImage(newWidth, newHeight, image.getType());
Graphics2D tool = rotated.createGraphics();
AffineTransform transformer = new AffineTransform();
transformer.rotate(angle, image.getWidth()/2, image.getHeight()/2);
tool.drawImage(image, transformer, null);
tool.dispose();
return rotated;
}
}
However, as the title suggests, the image gets cut off at the top and left sides of the image when rotated as shown:
Picture of rotated tank body:
So I have looked at many different forums but I could not solve my problem. I could add whitespace around the image, but that interferes a lot with collision detection which I plan to do later on. I know that it has to do something with the original display being smaller than the display of the rotated image, and I have tried to translate accordingly in many ways. If I translate with this line of code specifically,
transformer.translate((newWidth - image.getWidth())/2, (newHeight - image.getHeight())/2);
Then the image (tank body) rotates without cutting, but bounces out of place as shown (I drew a rectangle to show where it was):
Picture of rotated tank with translation:
I also have tried negating the translations too but it only avails to funky movements.
So, I really have no clue how to solve this, and I have been spending too much time on this problem. I would really appreciate a helpful answer that directly edits my method if possible.
Answer
So here is the opening idea that I needed to realize to answer this problem.
The method to translate and rotate is meant so that the image is not cut off. However, it won't be around the center as intended as seen in the 3rd picture. But again, the method is not intended to recenter it. The painting code itself needs to account for this shift. I simply added variables to account for this:
xOffset = (newWidth - image.getWidth())/2;
yOffset = (newHeight - image.getHeight())/2
And simply subtracted these from where I was painting the tank's body.
Thanks to #camickr for the solution
When rotating a square sprite around the center point, the target image should be larger than the original image by a factor of the square root of 2 (approx. 1.41). For example, a sprite will not be clipped at a rotation angle of 45 °.
I hope this information helps you to solve your problem.

Change alpha of image in java for method drawImage()

I'm trying to change the transparency of an image over time, and I'm doing this with the method drawImage() from java.awt.Graphics. I know there's a lot of different answers online about how to do this, but I can't find a one that is simple enough for me to understand and implement.
Let's just say I have a BufferedImage image, and I want to draw this image with a 50% opacity. How would I initialize image and what would I do to adjust the alpha level of the image when I draw it. It would be great if I could use the method drawImage() and do something with that to change the transparency of the image, but it's probably not that simple.
Never tried it, but I think the basic code would be:
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
g2d.setComposite(ac);
g2d.drawImage(...);
Using image filter.
float[] scales = { 1f, 1f, 1f, 0.1f };
float[] offsets = new float[4];
RescaleOp rop = new RescaleOp(scales, offsets, null);
g2d.drawImage(buffimg, rop, 0, 0);
4th element in scales array is transparency, this value goes between 0 - 1
Answer by camickr will make the entire component apply the alpha including all inner components. But that will be much faster.
Warning: Use Image Filters with Care
ref: http://www.informit.com/articles/article.aspx?p=1013851&seqNum=2

Merging Pictures in sequence

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);

Adding/override one image to another image at specific position?

I want to add an image to another image at specific position either it would be pixels or cm or (x,y). I have to do it by java programming using JAI(Java Advanced Imaging).
I googled to get sample code.
I got replacing ,adding at the end only.But not at specific position.
Any idea is appreciatable.
Laxman chowdary
BufferedImage sourceImage = ImageIO.read("myImage");
BufferedImage overlayImage = ImageIO.read("myOverlay");
Graphics2D g2Source = sourceImage.createGraphics();
g2Source.drawImage(overlayImage, x, y, null);
g2Source.dispose();

Rotational Pixel-Perfect Collision Detection

So I am working on an Android game and I have two images on the screen. I currently have the pixel-perfect collision detection working great. My problem is when I rotate one of the images and I check the pixels for a collision. The pixels are still oriented in the original way the image was loaded, so it is not as perfect as it was... I can get all of the pixels in an array, or a 2d array. But I am currently just accessing them by the getPixel(x, y) method in the Bitmap class.
Does anyone know of an algorithm to rotate the values in an array based on an arbitrary number of degrees? Or any other way of solving this problem?
Have you looked at AffineTransform?
It's what I have used to rotate sprites and images in the past.
I used this code to rotate and get a pixel value from an image:
Image rotatedImage = new BufferedImage(imageToRotate.getHeight(null), imageToRotate.getWidth(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = (Graphics2D) rotatedImage.getGraphics();
// Set rotation here
g2d.rotate(Math.toRadians(90.0));
g2d.drawImage(imageToRotate, 0, -rotatedImage.getWidth(null), null);
g2d.dispose();
int pixelColor = ((BufferedImage)rotatedImage).getRGB(x, y);

Categories

Resources