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:
parent
bf69b38056
commit
e465ed0850
@ -453,6 +453,7 @@ TEXTURES = \
|
|||||||
textures/textures_image_generation \
|
textures/textures_image_generation \
|
||||||
textures/textures_image_loading \
|
textures/textures_image_loading \
|
||||||
textures/textures_image_processing \
|
textures/textures_image_processing \
|
||||||
|
textures/textures_image_rotate \
|
||||||
textures/textures_image_text \
|
textures/textures_image_text \
|
||||||
textures/textures_to_image \
|
textures/textures_to_image \
|
||||||
textures/textures_raw_data \
|
textures/textures_raw_data \
|
||||||
|
79
examples/textures/textures_image_rotate.c
Normal file
79
examples/textures/textures_image_rotate.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*******************************************************************************************
|
||||||
|
*
|
||||||
|
* raylib [textures] example - Image Rotation
|
||||||
|
*
|
||||||
|
* Example originally created with raylib 1.0, last time updated with raylib 1.0
|
||||||
|
*
|
||||||
|
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||||
|
* BSD-like license that allows static linking with closed source software
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5)
|
||||||
|
*
|
||||||
|
********************************************************************************************/
|
||||||
|
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
#define NUM_TEXTURES 3
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Program main entry point
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
// Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
|
|
||||||
|
InitWindow(screenWidth, screenHeight, "raylib [textures] example - texture rotation");
|
||||||
|
|
||||||
|
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||||
|
Image image45 = LoadImage("resources/raylib_logo.png");
|
||||||
|
Image image90 = LoadImage("resources/raylib_logo.png");
|
||||||
|
Image imageNeg90 = LoadImage("resources/raylib_logo.png");
|
||||||
|
|
||||||
|
ImageRotate(&image45, 45);
|
||||||
|
ImageRotate(&image90, 90);
|
||||||
|
ImageRotate(&imageNeg90, -90);
|
||||||
|
|
||||||
|
Texture2D textures[NUM_TEXTURES] = { 0 };
|
||||||
|
|
||||||
|
textures[0] = LoadTextureFromImage(image45);
|
||||||
|
textures[1] = LoadTextureFromImage(image90);
|
||||||
|
textures[2] = LoadTextureFromImage(imageNeg90);
|
||||||
|
|
||||||
|
int currentTexture = 0;
|
||||||
|
//---------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Main game loop
|
||||||
|
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||||
|
{
|
||||||
|
// Update
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT) || IsKeyPressed(KEY_RIGHT))
|
||||||
|
{
|
||||||
|
currentTexture = (currentTexture + 1)%NUM_TEXTURES; // Cycle between the textures
|
||||||
|
}
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
BeginDrawing();
|
||||||
|
|
||||||
|
ClearBackground(RAYWHITE);
|
||||||
|
|
||||||
|
DrawTexture(textures[currentTexture], screenWidth/2 - textures[currentTexture].width/2, screenHeight/2 - textures[currentTexture].height/2, WHITE);
|
||||||
|
|
||||||
|
EndDrawing();
|
||||||
|
//----------------------------------------------------------------------------------
|
||||||
|
}
|
||||||
|
|
||||||
|
// De-Initialization
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
for (int i = 0; i < NUM_TEXTURES; i++) UnloadTexture(textures[i]);
|
||||||
|
|
||||||
|
CloseWindow(); // Close window and OpenGL context
|
||||||
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
BIN
examples/textures/textures_image_rotate.png
Normal file
BIN
examples/textures/textures_image_rotate.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
@ -6757,6 +6757,21 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "ImageRotate",
|
||||||
|
"description": "Rotate image by input angle in degrees (-359 to 359) ",
|
||||||
|
"returnType": "void",
|
||||||
|
"params": [
|
||||||
|
{
|
||||||
|
"type": "Image *",
|
||||||
|
"name": "image"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "int",
|
||||||
|
"name": "degrees"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "ImageRotateCW",
|
"name": "ImageRotateCW",
|
||||||
"description": "Rotate image clockwise 90deg",
|
"description": "Rotate image clockwise 90deg",
|
||||||
|
@ -5266,6 +5266,15 @@ return {
|
|||||||
{type = "Image *", name = "image"}
|
{type = "Image *", name = "image"}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name = "ImageRotate",
|
||||||
|
description = "Rotate image by input angle in degrees (-359 to 359) ",
|
||||||
|
returnType = "void",
|
||||||
|
params = {
|
||||||
|
{type = "Image *", name = "image"},
|
||||||
|
{type = "int", name = "degrees"}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name = "ImageRotateCW",
|
name = "ImageRotateCW",
|
||||||
description = "Rotate image clockwise 90deg",
|
description = "Rotate image clockwise 90deg",
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -656,7 +656,7 @@
|
|||||||
<Param type="unsigned int" name="frames" desc="" />
|
<Param type="unsigned int" name="frames" desc="" />
|
||||||
</Callback>
|
</Callback>
|
||||||
</Callbacks>
|
</Callbacks>
|
||||||
<Functions count="517">
|
<Functions count="518">
|
||||||
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
|
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
|
||||||
<Param type="int" name="width" desc="" />
|
<Param type="int" name="width" desc="" />
|
||||||
<Param type="int" name="height" desc="" />
|
<Param type="int" name="height" desc="" />
|
||||||
@ -1685,6 +1685,10 @@
|
|||||||
<Function name="ImageFlipHorizontal" retType="void" paramCount="1" desc="Flip image horizontally">
|
<Function name="ImageFlipHorizontal" retType="void" paramCount="1" desc="Flip image horizontally">
|
||||||
<Param type="Image *" name="image" desc="" />
|
<Param type="Image *" name="image" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
|
<Function name="ImageRotate" retType="void" paramCount="2" desc="Rotate image by input angle in degrees (-359 to 359) ">
|
||||||
|
<Param type="Image *" name="image" desc="" />
|
||||||
|
<Param type="int" name="degrees" desc="" />
|
||||||
|
</Function>
|
||||||
<Function name="ImageRotateCW" retType="void" paramCount="1" desc="Rotate image clockwise 90deg">
|
<Function name="ImageRotateCW" retType="void" paramCount="1" desc="Rotate image clockwise 90deg">
|
||||||
<Param type="Image *" name="image" desc="" />
|
<Param type="Image *" name="image" desc="" />
|
||||||
</Function>
|
</Function>
|
||||||
|
@ -202,6 +202,7 @@ ImageDrawText|void|(Image *dst, Vector2 position, const char *text, int fontSize
|
|||||||
ImageDrawTextEx|void|(Image *dst, Vector2 position, Font font, const char *text, float fontSize, float spacing, Color color);|
|
ImageDrawTextEx|void|(Image *dst, Vector2 position, Font font, const char *text, float fontSize, float spacing, Color color);|
|
||||||
ImageFlipVertical|void|(Image *image);|
|
ImageFlipVertical|void|(Image *image);|
|
||||||
ImageFlipHorizontal|void|(Image *image);|
|
ImageFlipHorizontal|void|(Image *image);|
|
||||||
|
ImageRotate|void|(Image *image, int degrees);|
|
||||||
ImageRotateCW|void|(Image *image);|
|
ImageRotateCW|void|(Image *image);|
|
||||||
ImageRotateCCW|void|(Image *image);|
|
ImageRotateCCW|void|(Image *image);|
|
||||||
ImageColorTint|void|(Image *image, Color color);|
|
ImageColorTint|void|(Image *image, Color color);|
|
||||||
|
@ -1570,6 +1570,12 @@
|
|||||||
<Param name="Image *image" />
|
<Param name="Image *image" />
|
||||||
</Overload>
|
</Overload>
|
||||||
</KeyWord>
|
</KeyWord>
|
||||||
|
<KeyWord name="ImageRotate" func="yes">
|
||||||
|
<Overload retVal="void" descr="Rotate image by input angle in degrees (-359 to 359)">
|
||||||
|
<Param name="Image *image" />
|
||||||
|
<Param name="int degrees" />
|
||||||
|
</Overload>
|
||||||
|
</KeyWord>
|
||||||
<KeyWord name="ImageRotateCW" func="yes">
|
<KeyWord name="ImageRotateCW" func="yes">
|
||||||
<Overload retVal="void" descr="Rotate image clockwise 90deg">
|
<Overload retVal="void" descr="Rotate image clockwise 90deg">
|
||||||
<Param name="Image *image" />
|
<Param name="Image *image" />
|
||||||
|
@ -346,6 +346,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 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 ImageFlipVertical(Image *image); // Flip image vertically
|
||||||
RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally
|
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 ImageRotateCW(Image *image); // Rotate image clockwise 90deg
|
||||||
RLAPI void ImageRotateCCW(Image *image); // Rotate image counter-clockwise 90deg
|
RLAPI void ImageRotateCCW(Image *image); // Rotate image counter-clockwise 90deg
|
||||||
RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint
|
RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint
|
||||||
|
@ -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 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 ImageFlipVertical(Image *image); // Flip image vertically
|
||||||
RLAPI void ImageFlipHorizontal(Image *image); // Flip image horizontally
|
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 ImageRotateCW(Image *image); // Rotate image clockwise 90deg
|
||||||
RLAPI void ImageRotateCCW(Image *image); // Rotate image counter-clockwise 90deg
|
RLAPI void ImageRotateCCW(Image *image); // Rotate image counter-clockwise 90deg
|
||||||
RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint
|
RLAPI void ImageColorTint(Image *image, Color color); // Modify image color: tint
|
||||||
|
@ -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
|
// Rotate image clockwise 90deg
|
||||||
void ImageRotateCW(Image *image)
|
void ImageRotateCW(Image *image)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user