Flip horizontal / vertical

I’ve looked into this, and have mostly found older threads. I’m hoping since, there are some streamlined solutions, but I haven’t been able to find any. Is there any way to draw an image flipped? Or rather, I should say, what is the current, most streamlined way to draw an image flipped? This may get a little weirder, as I am also trying to consider drawing part of an image flipped.

Any direction would be awesome. Thanks!

You mean rotated. Ok, but by how ? Did you search on the internet (stackoverflow for example) ?

using:

site:stackoverflow.com rotate an image

I would take ‘flipped’ to mean: “rotate about an axis connecting opposite corners of the image”, not: “rotate about the z-axis”.

Edit: or indeed any axis in the plane of the image.

1 Like

Hey there - I mean flipped (mirrored), either over horizontal or vertical axis, like in other environments scaling to -1. I did find some methods in posts, many pointed to third party plug ins (which I’m not against), but were also quite old, so I was seeing if there were any newer methods that I’m just not discovering.

Compute the time it tooks…

PB_Rotate.Action

Sub Action() Handles Action
  // 
  // Rotate the cSource contents
  // and place it into cTarget
  // 
  Dim x,y As Integer
  Dim aColor As Color
  Dim sourceSurf As RGBSurface
  Dim targetSurf As RGBSurface
  Dim pTarget As New Picture(pSource.Width,pSource.Height)
  
  sourceSurf = pSource.RGBSurface
  targetSurf = pTarget.RGBSurface
  
  For x = 0 To pSource.Width
    For y = 0 To pSource.Height
      targetSurf.Pixel(x,y) = sourceSurf.Pixel(y,x)
      
      If UserCancelled Then Exit
    Next y
    If UserCancelled Then Exit
  Next x
  
  cTarget.Backdrop = pTarget
  cTarget.Refresh
End Sub

pSource is a Picture Property

I pasted the image in the left Canvas, the right canvas is the result of the code execution.

Is it OK for you ?

Wow I think so! For the purposes of testing all this, yes. I actually didn’t mean for someone to blast out code, but rather point me in the right direction, but I can’t thank you enough for testing that out and offering an already working solution! :slight_smile: I’ll try this out in a little while and see if I can integrate it into what I’m doing. I’ll have to see what additional weirdness comes from flipping a PART of an image, but I’ll see if I can get this working first as a test!

Maybe you can be interested in take a look to the Rotate and Translate properties of the Graphic class. You can see some hints about how to use them here: Rotate that Picture! – Xojo Programming Blog

This is faster than the speed of life for the 100 x 100 pixels @ 72 dpi (on an Apple Silicon M1 laptop / Ventura).

Of course, for a far larger/taller/300 dpi or >, you may have to modify the code or eventually takes a plug-in to achieve the task with reasonable time.

Some Disable code can be set (look at the documentation for real code).

Replace the Dim with Var.

NB: the solution comes while I was making google search for tutorial (not found)… so I read that somewhere and keep the basic idea (loop / x,y invert) in memory.

To extract a part of an image, I imagine you will start at:
X = horizontal start value (not 0)
Y = vertical start value (not 0)

Same for Width and Height (with some computations to not go out of bounds…).

I await to be tomorrow to read what you will do with that.

Awesome. I will keep you updated. These images are small. It should not much matter.

One rather simple solution occurred to me for the flip/picture part. I imagine I could convert that flipped surface into a picture and store it, yeah? If so, when I load a new image to the picker, I could just make three copies (default, flip h, flip v, and flip h&v) as pictures. Then, when I’m using the picker, just draw the appropriate picture part based on flip selection controls.

Another possibility is that I could just make a huge array of tile pictures. I could break the picker into all of the potential images, and all their respective potential flips (these would be 8x8px pieces…but lots of them), then build a pointer array of some sort to know what to draw.

Some thoughts I’m pondering.

Sub Paint(g As Graphics, areas() As Rect) Handles Paint
  
  g.Translate(g.Width/2.0,g.Height/2.0)
  g.Rotate(3.14/10.0)
  g.Scale(-1.0,1.0)
  g.DrawPicture(img,-g.Width/2.0,-g.Height/2.0,g.Width,g.Height,0,0,img.Width,img.Height)
    
End Sub

1 Like

Oh wow! See, now that’s the sort of thing I was looking for! This worked perfectly:

g.Translate(g.Width/2.0,g.Height/2.0)
g.Scale(-1.0,1.0)
g.DrawPicture(workAreaImage,-g.Width/2.0,-g.Height/2.0,g.Width,g.Height,0,0,workAreaImage.Width,workAreaImage.Height)

It’ll be a LITTLE more of a challenge of logic to draw parts from this.

I’m trying to figure out the best way to handle this. Either I can do it mathematically or via individual assets. Like - the picker will always remain static. When drawing a part of the picker, I have no flips easy, figured out mathematically. But if the stamp is supposed to be flipped vertically, I either can have a iteration of the picker picture, from which it is pulled (in which case, it has to do the math to translate to the new position…if it was on the top row, it would now be on the bottom row, etc), OR I could get the piece of the picker, create a stamp-sized asset out of it, then draw the stamp sized asset with the flip.

I think I can work my way through either, but any cliffs I might be looking at with either solution? Anything I’m not considering? Thanks!

FYI, if you will be doing more graphics manipulation like this and are not adverse to paying for a plugin, the Einhugur PictureEffectsRaw plugin does Flips plus much more:

https://www.einhugur.com/Html/PictureEffectsRaw/index.html

1 Like

Not adverse at all - for THIS purpose, that’s about all I need to do for graphic manipulation, but never know what I might need for the future :slight_smile:

if you create a new picture object u can use the .graphics property to draw a picture into too.
means you can create a method picNew=Flip(picOld) with the same calls in the paint event.
graphics also have a few clip methods. or use the arguments in drawpicture itself to crop.

Thanks - I’m not sure I follow. If I use g.DrawPicture for my stamp, I know I can crop down to the piece I need. Now I know how I can set up a flip of the whole picture. Is there an easy way to define the cropped area, THEN flip just the crop to show? For instance, If I have a 1024x1024px image, and I’m only looking at a 32x32px area in the top left corner, I crop to that area so I just have the 32x32px result, then flip THAT accordingly? Otherwise, I have to then read from the top RIGHT corner of the fully flipped image, right?

This is all super helpful!

I totally forgot that… and it is in the Documentation !

Joe:

have you looked at these examples projects:

Animation
DesktopOpenGLSurface.xojo_binary_project
GraphicsPath.xojo_binary_project
Graphing Sign Waves.xojo_binary_project
Interactive Grid.xojo_binary_project
Interactive Objects in a Canvas
Object2D Text Rotation.xojo_binary_project
Saving and Load Vector Graphics.xojo_binary_project
Sparkler.xojo_binary_project
System Colors.xojo_binary_project

(they are in the Graphics folder)

Hey there - yes, I’m slowly sort of working through a lot of things - with the help here in addition to the resources like what you’re describing, I’ve been making a lot of progress quickly! But there are still a lot of deep corners to examine. I actually have what I’m trying to accomplish mostly working. However, the code in the paint event for this canvas iterates through stamps to draw from a list, all of which may have different flip parameters. This is producing unexpected results upon iteration (it works fine for non-flipped things, reading coordinates from the table, so I know the table is working great, but beyond the first flipped, flipped stamps don’t work as they’re supposed to).

I have this suspicion that during the loop, setting the translation/scale are translating/scaling based on the last setting…so if in the first iteration, I set the translation and scale to get a flip, then in the next iteration, I have another flipped stamp, it’s translating/scaling based on the already changed translation and changed scale. It’s not setting the translation or scale, it’s translating and scaling based on the current translation. Is this a correct assumption?

If so, what would be the proper way to reset the translation / scale at the end of an iteration?

I’ll continue to dig into some of those projects as well to see if they help. If anyone has any thoughts, that would be great!

I may try to handle this with Objects instead, but curious mind wants to know about above for the sake of learning :slight_smile:

What I discovered is that for my purposes, I don’t need the translation. The following generally works. And yes, I found that I do have to reset the scale after drawing by writing again to negate it (affect the -1 scale by -1 to set it back to positive 1). Then, this seems to work for now.

'Draws the object on the canvas.
'original script- alone it works.
g.DrawPicture(Image, Left, Top)

//draws an image to the screen flipped vertically. It works.
g.Scale(1.0,-1.0)
g.DrawPicture(Image,Left,-1*(Top)-Image.Height/2)
g.Scale(1.0,-1.0) // reset the scale when we're done.


//draws an image to the screen flipped horizontally. It works.
g.Scale(-1.0,1.0)
g.DrawPicture(Image,-1*(Left)-Image.Width/2,Top)
g.Scale(-1.0,1.0) // reset the scale when we're done.


//draws an image to the screen flipped horizontally and vertically. It works.
g.Scale(-1.0,-1.0)
g.DrawPicture(Image,-1*(Left)-Image.Width/2,-1*(Top)-Image.Height/2)
g.Scale(-1.0,-1.0) // reset the scale when we're done.