Implement `rotate_90/rotate_180` functions to `Image`
This commit is contained in:
parent
9904a9db5a
commit
7e66903d56
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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" />
|
||||
|
|
Loading…
Reference in New Issue