summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorDane Madsen <[email protected]>2023-05-24 17:22:51 +1000
committerGitHub <[email protected]>2023-05-24 09:22:51 +0200
commite465ed0850106a3574d01363874ae49ef7e478c9 (patch)
tree937d11d54cac0c6b5282e6797f298aadf99524c1 /src
parentbf69b3805601627a509b92600c9b70efcddfedeb (diff)
downloadraylib-e465ed0850106a3574d01363874ae49ef7e478c9.tar.gz
raylib-e465ed0850106a3574d01363874ae49ef7e478c9.zip
Added ImageRotate (#3078)
* Added ImageRotate * Quick rename of the example * Update ImageRotate by changing doubles to floats and checking code convention * Update API
Diffstat (limited to 'src')
-rw-r--r--src/raylib.h1
-rw-r--r--src/rtextures.c59
2 files changed, 60 insertions, 0 deletions
diff --git a/src/raylib.h b/src/raylib.h
index 703e70c2..b2b82583 100644
--- a/src/raylib.h
+++ b/src/raylib.h
@@ -1268,6 +1268,7 @@ RLAPI void ImageMipmaps(Image *image);
RLAPI void ImageDither(Image *image, int rBpp, int gBpp, int bBpp, int aBpp); // Dither image data to 16bpp or lower (Floyd-Steinberg dithering)
RLAPI void ImageFlipVertical(Image *image); // Flip image vertically
RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally
+RLAPI void ImageRotate(Image *image, int degrees); // Rotate image by input angle in degrees (-359 to 359)
RLAPI void ImageRotateCW(Image *image); // Rotate image clockwise 90deg
RLAPI void ImageRotateCCW(Image *image); // Rotate image counter-clockwise 90deg
RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint
diff --git a/src/rtextures.c b/src/rtextures.c
index eeeebba8..b5e2a7f7 100644
--- a/src/rtextures.c
+++ b/src/rtextures.c
@@ -2118,6 +2118,65 @@ void ImageFlipHorizontal(Image *image)
}
}
+// Rotate image in degrees
+void ImageRotate(Image *image, int degrees)
+{
+ // Security check to avoid program crash
+ if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return;
+
+ if (image->mipmaps > 1) TRACELOG(LOG_WARNING, "Image manipulation only applied to base mipmap level");
+ if (image->format >= PIXELFORMAT_COMPRESSED_DXT1_RGB) TRACELOG(LOG_WARNING, "Image manipulation not supported for compressed formats");
+ else
+ {
+ float rad = degrees * PI / 180.0f;
+ float sinRadius = sin(rad);
+ float cosRadius = cos(rad);
+
+ int width = abs(image->width * cosRadius) + abs(image->height * sinRadius);
+ int height = abs(image->height * cosRadius) + abs(image->width * sinRadius);
+
+ int bytesPerPixel = GetPixelDataSize(1, 1, image->format);
+ unsigned char *rotatedData = (unsigned char *)RL_CALLOC(width * height, bytesPerPixel);
+
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ float oldX = ((x - width / 2.0f) * cosRadius + (y - height / 2.0f) * sinRadius) + image->width / 2.0f;
+ float oldY = ((y - height / 2.0f) * cosRadius - (x - width / 2.0f) * sinRadius) + image->height / 2.0f;
+
+ if (oldX >= 0 && oldX < image->width && oldY >= 0 && oldY < image->height)
+ {
+ int x1 = (int)floor(oldX);
+ int y1 = (int)floor(oldY);
+ int x2 = MIN(x1 + 1, image->width - 1);
+ int y2 = MIN(y1 + 1, image->height - 1);
+
+ float px = oldX - x1;
+ float py = oldY - y1;
+
+ for (int i = 0; i < bytesPerPixel; i++)
+ {
+ float f1 = ((unsigned char *)image->data)[(y1 * image->width + x1) * bytesPerPixel + i];
+ float f2 = ((unsigned char *)image->data)[(y1 * image->width + x2) * bytesPerPixel + i];
+ float f3 = ((unsigned char *)image->data)[(y2 * image->width + x1) * bytesPerPixel + i];
+ float f4 = ((unsigned char *)image->data)[(y2 * image->width + x2) * bytesPerPixel + i];
+
+ float val = f1 * (1 - px) * (1 - py) + f2 * px * (1 - py) + f3 * (1 - px) * py + f4 * px * py;
+
+ rotatedData[(y * width + x) * bytesPerPixel + i] = (unsigned char)val;
+ }
+ }
+ }
+ }
+
+ RL_FREE(image->data);
+ image->data = rotatedData;
+ image->width = width;
+ image->height = height;
+ }
+}
+
// Rotate image clockwise 90deg
void ImageRotateCW(Image *image)
{