I'm making a top-down shooter game that relies on the avatar always being rotated pointing to the mouse cursor. I achieve rotation like this:
//Rendering. context.save(); //Save the context state, we're about to change it a lot. context.translate(position[0] + picture.width/2, position[1] + picture.height/2); //Translate the context to the center of the image. context.rotate(phi); //Rotate the context by the object's phi. context.drawImage(picture.image, -picture.width/2, -picture.height/2); //Draw the image at the appropriate position (center of the image = [0, 0]). context.restore(); //Get the state back.
When the phi
is zero, the image is rendered in its normal quality, with sharp edges and detectable pixels. But, when I set the phi
to a nonzero value (actually, when it's not 0
, Pi/2
, Pi
, Pi+Pi/2
or 2Pi
), the image looses it's sharpness and the individual pixels can't be seen anymore, because they are blurred out.
Here's a screenshot (sorry about the general bad quality of the screenshot, but I think that the difference is more than noticeable):
This is, well, a bit unacceptable. I can't have the images always blurred out! Why is this happening and can I solve it?
The actual rotation by 90,180,270 degrees will not have any effect on the image quality at all. Having said that if you start with a JPG file and rotate in PhotoShop and resave the image will be recompressed and loose some quality. If you want to only rotate a JPG use a program that supports lossless rotation.
To perform a lossless left/right rotate or vertical/horizontal flip, go to Tools > JPEG Lossless Rotate. Alternatively, you can also find the Tools menu by right clicking on the image. The rotate clockwise or counterclockwise icons are also lossless for JPEG files.
When an image is rotated, the new locations of some pixels may be outside the image if the input and output image sizes are the same (see Figure 4.3, in which the corners of the input would not have fit within the resultant image).
The rotation operator performs a geometric transform which maps the position of a picture element in an input image onto a position in an output image by rotating it through a user-specified angle about an origin .
You could try
context.imageSmoothingEnabled = false;
See docs:
context.imageSmoothingEnabled [ = value ]
Returns whether pattern fills and the drawImage() method will attempt to smooth images if they have to rescale them (as opposed to just rendering the images with "big pixels").
Can be set, to change whether images are smoothed (true) or not (false).
If you want a true pixel-art retro style effect, you'd need to manually create rotated sprite images for several angles, look up the appropriate sprite for the current value of phi
, and draw it without rotation. This obviously requires a fair amount of art work!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With