Added ImageRotate (#3078)

* Added ImageRotate

* Quick rename of the example

* Update ImageRotate by changing doubles to floats and checking code convention

* Update API
This commit is contained in:
Dane Madsen
2023-05-24 17:22:51 +10:00
committed by GitHub
parent bf69b38056
commit e465ed0850
12 changed files with 429 additions and 247 deletions

View File

@@ -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)
{