Implement `rotate_90/rotate_180` functions to `Image`

This commit is contained in:
Yuri Rubinsky 2022-07-14 22:20:12 +03:00
parent 9904a9db5a
commit 7e66903d56
3 changed files with 121 additions and 0 deletions

View File

@ -1339,6 +1339,108 @@ void Image::crop(int p_width, int p_height) {
crop_from_point(0, 0, p_width, p_height);
}
void Image::rotate_90(ClockDirection p_direction) {
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats.");
ERR_FAIL_COND_MSG(width <= 1, "The Image width specified (" + itos(width) + " pixels) must be greater than 1 pixels.");
ERR_FAIL_COND_MSG(height <= 1, "The Image height specified (" + itos(height) + " pixels) must be greater than 1 pixels.");
int saved_width = height;
int saved_height = width;
if (width != height) {
int n = MAX(width, height);
resize(n, n, INTERPOLATE_NEAREST);
}
bool used_mipmaps = has_mipmaps();
if (used_mipmaps) {
clear_mipmaps();
}
{
uint8_t *w = data.ptrw();
uint8_t src[16];
uint8_t dst[16];
uint32_t pixel_size = get_format_pixel_size(format);
// Flip.
if (p_direction == CLOCKWISE) {
for (int y = 0; y < height / 2; y++) {
for (int x = 0; x < width; x++) {
_get_pixelb(x, y, pixel_size, w, src);
_get_pixelb(x, height - y - 1, pixel_size, w, dst);
_put_pixelb(x, height - y - 1, pixel_size, w, src);
_put_pixelb(x, y, pixel_size, w, dst);
}
}
} else {
for (int y = 0; y < height; y++) {
for (int x = 0; x < width / 2; x++) {
_get_pixelb(x, y, pixel_size, w, src);
_get_pixelb(width - x - 1, y, pixel_size, w, dst);
_put_pixelb(width - x - 1, y, pixel_size, w, src);
_put_pixelb(x, y, pixel_size, w, dst);
}
}
}
// Transpose.
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (x < y) {
_get_pixelb(x, y, pixel_size, w, src);
_get_pixelb(y, x, pixel_size, w, dst);
_put_pixelb(y, x, pixel_size, w, src);
_put_pixelb(x, y, pixel_size, w, dst);
}
}
}
}
if (saved_width != saved_height) {
resize(saved_width, saved_height, INTERPOLATE_NEAREST);
} else if (used_mipmaps) {
generate_mipmaps();
}
}
void Image::rotate_180() {
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats.");
ERR_FAIL_COND_MSG(width <= 1, "The Image width specified (" + itos(width) + " pixels) must be greater than 1 pixels.");
ERR_FAIL_COND_MSG(height <= 1, "The Image height specified (" + itos(height) + " pixels) must be greater than 1 pixels.");
bool used_mipmaps = has_mipmaps();
if (used_mipmaps) {
clear_mipmaps();
}
{
uint8_t *w = data.ptrw();
uint8_t src[16];
uint8_t dst[16];
uint32_t pixel_size = get_format_pixel_size(format);
for (int y = 0; y < height / 2; y++) {
for (int x = 0; x < width; x++) {
_get_pixelb(x, y, pixel_size, w, src);
_get_pixelb(width - x - 1, height - y - 1, pixel_size, w, dst);
_put_pixelb(width - x - 1, height - y - 1, pixel_size, w, src);
_put_pixelb(x, y, pixel_size, w, dst);
}
}
}
if (used_mipmaps) {
generate_mipmaps();
}
}
void Image::flip_y() {
ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot flip_y in compressed or custom image formats.");
@ -3217,6 +3319,9 @@ void Image::_bind_methods() {
ClassDB::bind_method(D_METHOD("decompress"), &Image::decompress);
ClassDB::bind_method(D_METHOD("is_compressed"), &Image::is_compressed);
ClassDB::bind_method(D_METHOD("rotate_90", "direction"), &Image::rotate_90);
ClassDB::bind_method(D_METHOD("rotate_180"), &Image::rotate_180);
ClassDB::bind_method(D_METHOD("fix_alpha_edges"), &Image::fix_alpha_edges);
ClassDB::bind_method(D_METHOD("premultiply_alpha"), &Image::premultiply_alpha);
ClassDB::bind_method(D_METHOD("srgb_to_linear"), &Image::srgb_to_linear);

View File

@ -254,6 +254,9 @@ public:
void crop_from_point(int p_x, int p_y, int p_width, int p_height);
void crop(int p_width, int p_height);
void rotate_90(ClockDirection p_direction);
void rotate_180();
void flip_x();
void flip_y();

View File

@ -378,6 +378,19 @@
Converts a standard RGBE (Red Green Blue Exponent) image to an sRGB image.
</description>
</method>
<method name="rotate_180">
<return type="void" />
<description>
Rotates the image by [code]180[/code] degrees. The width and height of the image must be greater than [code]1[/code].
</description>
</method>
<method name="rotate_90">
<return type="void" />
<argument index="0" name="direction" type="int" enum="ClockDirection" />
<description>
Rotates the image in the specified [code]direction[/code] by [code]90[/code] degrees. The width and height of the image must be greater than [code]1[/code]. If the width and height are not equal, the image will be resized.
</description>
</method>
<method name="save_exr" qualifiers="const">
<return type="int" enum="Error" />
<argument index="0" name="path" type="String" />