Recent

Author Topic: SDL2 image rotation Problem  (Read 12909 times)

Pe3s

  • Hero Member
  • *****
  • Posts: 590
Re: SDL2 image rotation Problem
« Reply #15 on: January 13, 2025, 05:07:24 pm »
I found a solution to my problem only that in Delphi there is a component ImageEn however, you have to reckon with the cost of buying a license. However, for graphics it is a great solution.
Greetings :)

TRon

  • Hero Member
  • *****
  • Posts: 3925
Re: SDL2 Fit image rotation bug
« Reply #16 on: January 13, 2025, 10:00:09 pm »
By the way, I can compile your project, but I get this error when I try to run it:
The SDLCreateWindowFrom function in combination with LCL only works for the Windows platform (other platforms/widgetsets require a special handle that allows for graphics to be drawn onto the canvas).

Can anyone help or is it over with the code questions :)
I order to be able to test your code it needs to be rewritten when doing so for a platform besides Windows.

Seenkao's questions are still valid because I also do not have a clue what it is that you are actually trying to achieve. The rotating works with keeping the aspect ratio of the original image. You do not seem to want that but do not mention what the result should become.

Should the image be resized to match the canvas, should the image be scaled to match the largest dimensions keeping the original aspect ratio and cut off everything that is out of range, should it resize the size of the canvas to match the (rotated)_ picture etc. etc.

No answers means we would have to come up with all possible scenario's while you seem to fancy only one of them (whatever that scenario might be) :)
I do not have to remember anything anymore thanks to total-recall.

Pe3s

  • Hero Member
  • *****
  • Posts: 590
Re: SDL2 image rotation Problem
« Reply #17 on: January 14, 2025, 08:44:26 am »
@TRon I want that after rotation the image would fit according to the proportions of the window, plot, etc.

Let's take such an example, for example, from the IrfanView viewer if we rotate the image, then the image dimensions swap places and the image is adjusted to the window.

In my code if we read an image for example in portrait format then after rotation the image is smaller and does not fit the window.

Greetings


Pe3s

  • Hero Member
  • *****
  • Posts: 590
Re: SDL2 image rotation Problem
« Reply #18 on: January 14, 2025, 10:19:23 am »
so I wonder if it would not help to dynamically swap the dimensions of the plot, only that sdl permanently holds the dimension of the loaded image.

- If we load an image with dimensions: 200x300px then after a 90 degree rotation the dimensions should change to 300x200, after another rotation 200x300, after another 300x200 and finally return to 200x300, and the image should be adjusted to the proportions of the window in the case of large images.

Fred vS

  • Hero Member
  • *****
  • Posts: 3475
    • StrumPract is the musicians best friend
Re: SDL2 image rotation Problem
« Reply #19 on: January 14, 2025, 11:18:08 pm »
Hello Pe3s.

In case you are not angry with me, here code to rotate image with SDL2.
Yes, Grok helps me but I must help him a lot too.
There are 2 images rendered, one from the png and the other is a rotation of the first image.

Code: Pascal  [Select][+][-]
  1. var
  2.  image_texture: PSDL_Texture = nil;
  3.  rotated_image_texture: PSDL_Texture = nil;
  4.  image_rect: TSDL_Rect = (x: 0; y: 0; w: 0; h: 0);
  5.  rotated_image_rect: TSDL_Rect = (x: 0; y: 0; w: 0; h: 0);
  6.  
  7. ...
  8.  
  9. procedure load_images;
  10. var
  11. image_surface: PSDL_Surface;
  12. begin
  13.   // Load first image
  14.   image_surface := IMG_Load('/path/of/image.png');
  15.   if image_surface = nil then
  16.   begin
  17.     WriteLn('Unable to load image! SDL_image Error: ', IMG_GetError());
  18.     Exit;
  19.   end else
  20.   begin
  21.     WriteLn('First Image loaded successfully.');
  22.   end;
  23.  
  24.   image_texture := SDL_CreateTextureFromSurface(renderer, image_surface);
  25.   SDL_QueryTexture(image_texture, nil, nil, @image_rect.w, @image_rect.h);
  26.  
  27.   // Use the same texture for rotation during rendering
  28.   rotated_image_texture := image_texture;
  29.   SDL_QueryTexture(rotated_image_texture, nil, nil, @rotated_image_rect.w, @rotated_image_rect.h);
  30.  
  31.   SDL_FreeSurface(image_surface);
  32. end;
  33.  
  34. procedure render;
  35. begin
  36.   SDL_SetRenderDrawColor(renderer, 50, 50, 50, 255);
  37.   SDL_RenderClear(renderer);
  38.  
  39.   // Draw images first from png
  40.   if Assigned(image_texture) then
  41.   begin
  42.     SDL_RenderCopy(renderer, image_texture, nil, @image_rect);
  43.   end;
  44.  
  45.   // Draw rotated image
  46.   if Assigned(rotated_image_texture) then
  47.   begin
  48.     SDL_RenderCopyEx(renderer, rotated_image_texture, nil, @rotated_image_rect, 90, nil, SDL_FLIP_NONE);
  49.   end;
  50.  
  51.    SDL_QueryTexture(rotated_image_texture, nil, nil, @rotated_width, @rotated_height);
  52.    
  53.     // Adjust the rectangle for left alignment
  54.     rotated_image_rect.x := image_rect.w + 150 ;// Left align
  55.     rotated_image_rect.y := 120; // Position as before or adjust vertically if needed
  56.     rotated_image_rect.w := rotated_width; // Width stays the same as it was after rotation
  57.     rotated_image_rect.h := rotated_height; // Height stays the same as it was after rotation
  58. end;
  59.  
« Last Edit: January 14, 2025, 11:51:08 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

Pe3s

  • Hero Member
  • *****
  • Posts: 590
Re: SDL2 image rotation Problem
« Reply #20 on: January 15, 2025, 10:12:11 am »
@Fred vS, I am not angry, I adhere to the principle that a smile is better than anger. I'm just looking for a solution.
I am grateful for any comment and help .
Thank you and Greetings with a smile.

Fred vS

  • Hero Member
  • *****
  • Posts: 3475
    • StrumPract is the musicians best friend
Re: SDL2 image rotation Problem
« Reply #21 on: January 15, 2025, 12:23:28 pm »
@Fred vS, I am not angry, I adhere to the principle that a smile is better than anger. I'm just looking for a solution.
I am grateful for any comment and help .
Thank you and Greetings with a smile.

Hello Pe3s.
Nice answer and good feeling. ;D
I am in the same boat as you, exploring sdl2.

In a previous post I told you about the fantastic graphical tool: BGRABitmap.
It can be perfectly used with sdl2 and will allow to do complicated image manipulations.
Here is the code that loads a image.png into an sdl2 image and rotates it using BGRABitmap and this rotated bitmap is filled into another sdl2 image.

Code: Pascal  [Select][+][-]
  1. uses
  2.   SysUtils, SDL2, SDL2_image, BGRABitmap, BGRABitmapTypes;
  3.  
  4. ...
  5.  
  6. var
  7.   window: PSDL_Window;
  8.   renderer: PSDL_Renderer;
  9.   running: Boolean = True;
  10.   original_texture, rotated_texture: PSDL_Texture;
  11.   original_rect, rotated_rect: TSDL_Rect;
  12.  
  13. ...
  14.  
  15. procedure load_and_process_images;
  16. var
  17.   surface: PSDL_Surface;
  18.   bgraBitmap, rotatedBitmap: TBGRABitmap;
  19.   rotated_surface: PSDL_Surface;
  20. begin
  21.   // Load image with SDL2
  22.   surface := IMG_Load('/path/to/image.png');
  23.   if surface = nil then
  24.   begin
  25.     WriteLn('Unable to load image! SDL_image Error: ', IMG_GetError());
  26.     Exit;
  27.   end;
  28.  
  29.   try
  30.     // Convert SDL_Surface to BGRABitmap for manipulation
  31.     bgraBitmap := TBGRABitmap.Create(surface^.w, surface^.h, BGRAWhite);
  32.     Move(surface^.pixels^, bgraBitmap.Data^, surface^.w * surface^.h * 4);
  33.  
  34.     // Rotate using BGRABitmap
  35.     rotatedBitmap := bgraBitmap.RotateCW;
  36.     try
  37.       // Convert back to SDL textures
  38.       original_texture := SDL_CreateTextureFromSurface(renderer, surface);
  39.       SDL_QueryTexture(original_texture, nil, nil, @original_rect.w, @original_rect.h);
  40.       original_rect.x := 10;
  41.       original_rect.y := 10;
  42.  
  43.       // Create a new surface for the rotated image with the same pixel format as the original
  44.       rotated_surface := SDL_CreateRGBSurface(0, rotatedBitmap.Width, rotatedBitmap.Height,
  45.                                                surface^.format^.BitsPerPixel,
  46.                                                surface^.format^.Rmask,
  47.                                                surface^.format^.Gmask,
  48.                                                surface^.format^.Bmask,
  49.                                                surface^.format^.Amask);
  50.       if rotated_surface <> nil then
  51.       begin
  52.         // Copy the bitmap data, making sure color channels are in the correct order
  53.         Move(rotatedBitmap.Data^, rotated_surface^.pixels^, rotatedBitmap.NbPixels * 4);
  54.         rotated_texture := SDL_CreateTextureFromSurface(renderer, rotated_surface);
  55.         SDL_QueryTexture(rotated_texture, nil, nil, @rotated_rect.w, @rotated_rect.h);
  56.         rotated_rect.x := 10;
  57.         rotated_rect.y := original_rect.y + original_rect.h + 10;
  58.         SDL_FreeSurface(rotated_surface);
  59.       end else
  60.       begin
  61.         WriteLn('Failed to create surface for rotated image: ', SDL_GetError());
  62.       end;
  63.     finally
  64.       rotatedBitmap.Free;
  65.     end;
  66.   finally
  67.     bgraBitmap.Free;
  68.     SDL_FreeSurface(surface);
  69.   end;
  70. end;
  71.  
  72. procedure render;
  73. begin
  74.   SDL_SetRenderDrawColor(renderer, 50, 50, 50, 255);
  75.   SDL_RenderClear(renderer);
  76.  
  77.   if Assigned(original_texture) then
  78.     SDL_RenderCopy(renderer, original_texture, nil, @original_rect);
  79.  
  80.   if Assigned(rotated_texture) then
  81.     SDL_RenderCopy(renderer, rotated_texture, nil, @rotated_rect);
  82.  
  83.   SDL_RenderPresent(renderer);
  84. end;
  85.  
« Last Edit: January 15, 2025, 12:46:15 pm by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

TRon

  • Hero Member
  • *****
  • Posts: 3925
Re: SDL2 image rotation Problem
« Reply #22 on: January 15, 2025, 07:55:17 pm »
@TRon I want that after rotation the image would fit according to the proportions of the window, plot, etc.
Ok, in that case you need to be prepared and expect that the image is stretched. But then the question becomes how to treat the contents of the picture itself. In case the dimensions of the graphical content do not match the window then you can either opt for resizing the image to the smallest available window height/width and cut of the other direction or you would have to deal with the fact that there are either horizontal or vertical borders. The other option is the fit the image into the window dimensions but then the image will need to be resized to match those dimensions (in that process the aspect ratio of the contents of the graphics will change accordingly).

@Fred:
Nice solution (and I did not know that you could mix bgra with sdl) but realize that the original code in the rar archive from TS already rotated the image correctly. The problem lies in how to present the rotated picture in to the available canvas space (window). TS is unclear on how that should behave and there are several situations possible.
« Last Edit: January 15, 2025, 08:03:45 pm by TRon »
I do not have to remember anything anymore thanks to total-recall.

Fred vS

  • Hero Member
  • *****
  • Posts: 3475
    • StrumPract is the musicians best friend
Re: SDL2 image rotation Problem
« Reply #23 on: January 16, 2025, 01:13:15 am »
@Fred:
 (and I did not know that you could mix bgra with sdl)
BGRABitmap is fabulous.  ;)
There is the full demo with SDL2 pascal headers here.

@Fred:
 but realize that the original code in the rar archive from TS already rotated the image correctly.
Yes but the result is stretched using width and length of original picture.
With the code I provided it is rotated with width = original height and height = original width.
« Last Edit: January 16, 2025, 01:28:47 am by Fred vS »
I use Lazarus 2.2.0 32/64 and FPC 3.2.2 32/64 on Debian 11 64 bit, Windows 10, Windows 7 32/64, Windows XP 32,  FreeBSD 64.
Widgetset: fpGUI, MSEgui, Win32, GTK2, Qt.

https://github.com/fredvs
https://gitlab.com/fredvs
https://codeberg.org/fredvs

TRon

  • Hero Member
  • *****
  • Posts: 3925
Re: SDL2 image rotation Problem
« Reply #24 on: January 19, 2025, 12:39:30 am »
Yes but the result is stretched using width and length of original picture.
With the code I provided it is rotated with width = original height and height = original width.
Leaving out the LCL related code and only focusing on the SDL side of the graphics the code already works correctly. That is what I am trying to tell  :)

PS: in case someone from FPC meets SDL happens to read this: The 2.2 stable release (SDL2-for-Pascal-2.2-stable.tar.gz) seems to be missing SDL_BlitScaled, e.g.
Code: Pascal  [Select][+][-]
  1. function SDL_BlitScaled(src: PSDL_Surface; const srcrect: PSDL_Rect; dst: PSDL_Surface; dstrect: PSDL_Rect): cint; cdecl; inline;
  2. begin
  3.   result := SDL_BlitSurfaceScaled(src, srcrect, dst, dstrect);
  4. end;
  5.  
I do not have to remember anything anymore thanks to total-recall.

 

TinyPortal © 2005-2018