image:rotatedImage(90) delivers a result offset up and left by 1 pixel, with the top and left lines of pixels deleted, resulting in a smaller image when it should be the same size. Image below.
This seems to be new recently—probably in SDK 1.12—or I would have noticed before now. Only 90° rotations seem to be affected.
To reproduce
This main.lua makes a 10px circle and a 90° rotated copy. They should look identical, but one is offset up/left and cropped. (The third circle tests a 45° rotation, which looks fine—it's just offset a bit since its bounding rect is larger.)
import "CoreLibs/graphics"
local pd <const> = playdate
local gfx <const> = pd.graphics
function pd.update()
end
original = gfx.image.new(10, 10)
gfx.pushContext(original)
gfx.fillCircleInRect(0, 0, 10, 10)
gfx.popContext()
rotated90 = original:copy()
rotated45 = original:copy()
rotated90 = rotated90:rotatedImage(90)
rotated45 = rotated45:rotatedImage(45)
original:draw(10, 10)
rotated90:draw(30, 10) --Should look identical but doesn't
rotated45:draw(50, 10)
(It happens regardless of whether the image is a perfect square or rectangular, but a square makes it easier to see.)
So uh, this is a pretty freaking big issue. I'm using the latest SDK and this is still happening. I'm trying to make a pinball game with a portrait mode which involves rotating all the sprites 90 degrees. I'm using sprite:setRotation. Any plans to fix this? Any workarounds?
I use a workaround that's adapted from TheMediocritist's post earlier:
local USE_ROTATION_WORKAROUND <const> = true
function rotated_image(image, angle)
if angle == 0 then
return image
end
if USE_ROTATION_WORKAROUND then
local width <const>, height <const> = image:getSize()
local transformed_image = gfx.image.new(width, height, gfx.kColorClear)
gfx.pushContext(transformed_image)
image:drawRotated(width / 2, height / 2, angle)
gfx.popContext()
return transformed_image
end
return image:rotatedImage(angle)
end