imageview update/refresh

Post

Posted
Rating:
#1 (In Topic #1540)
Regular
DIYTinkerer is in the usergroup ‘Regular’
Hi,

I've been struggling with this for about a week I've read the relevant parts of the wiki and some chapters of a gambas online book, but I still cant work out what Im doing wrong.

I have one form with an imageview on it. I load and display an image, then I directly edit the pixels in the image to put a cross in the position where I double click on the image. All good so far…

I've stored the points where the crosses need to be drawn in an array.
I detect a CTRL+Z 'undo'
I then copy an unedited copy of the image into the working copy, and to an inageview.update(workingcopy)
I then re draw all but the last cross.
The problem I have is only the first undo works, sometimes none work, but I can't work out what I'm doing wrong, I've used breakpoints and debug statements to help work out what is going wrong and can see that the ImageView doesn't appear to be refreshing with the clean image,

Attachment

Code (gambas)

  1. ' Gambas class file
  2.  
  3. ''This is the main form
  4.  
  5. Public Coord[4, 2] As Float               'this holds the coordinates that define the limb
  6. Public originalImage As Image             'create image object to hold original image
  7. Public workingCopyImage As Image          'image object to hold working copy of image
  8. Public pointIndex As Integer = 0          'holds the number of crosses drawn
  9.  
  10. Public Sub Form_Open()
  11.   originalImage = Image.Load("MoonTest.jpg") ' load image from disk to originalImage object
  12.   workingCopyImage = originalImage 'copy originalImage
  13.   imageview1.Image = workingCopyImage 'load workingcopyimage into imageview object
  14.   pointIndex = 0
  15.  
  16. Public Sub imageView1_DblClick()
  17.   capturePoint()
  18.  
  19. Public Sub imageView1_KeyRelease()
  20.   imageView1.Mouse = Mouse.Arrow
  21.   If Key.control And Key.code = 90 Then 'CTRL+z
  22.     undo()
  23.  
  24. Public Sub capturePoint()
  25.  ''store the position of the mouse when doubleclicked in Coord[,]
  26.   Debug "pointIndex=" & pointIndex
  27.   Coord[pointIndex, 0] = ((Mouse.X + imageView1.Scrollx) / imageView1.Zoom)
  28.   Coord[pointIndex, 1] = ((Mouse.Y + imageView1.Scrolly) / imageView1.Zoom)
  29.   drawCross(Coord[pointindex, 0], Coord[pointindex, 1])
  30.   If pointIndex < 3 Then 'just limit the number of points
  31.     pointIndex += 1
  32.  
  33. Public Sub undo()
  34.   Debug "Undo"
  35.   Dim f As Integer
  36.   If pointIndex = 0 Then 'nothing to undo
  37.   Debug "nothing to undo"
  38.   Return 'exit sub if there's nothing to do
  39.   Else
  40.     Debug "Copy original image into working copy - so all the crosses are removed"
  41.     workingCopyImage = originalImage
  42.     Debug "let's undo something"
  43.     pointIndex -= 1 'reduce point index by 1
  44.     'clear points from image
  45.     Debug "load new image into imageview1"
  46.     imageview1.update(workingCopyImage)' Refresh the view, but don't redraw *everything*.
  47.     Debug "pointIndex after undo: " & pointIndex
  48.     For f = 0 To pointIndex - 1
  49.       Debug "coords to redraw (" & Coord[f, 0] & "," & Coord[f, 1] & ")"
  50.       drawCross(Coord[f, 0], Coord[f, 1]) ' Redraw the existing crosses.
  51.     Next
  52.   Endif
  53.  
  54. ''drawCross Draws a cross in the screen centered at (x,y)
  55. Public Sub drawCross(x As Integer, y As Integer)
  56.   ''draws a small cross at the x,y coordinates
  57.   Debug "Draw cross directly on working copy image"
  58.   Dim z, sx, sy As Single
  59.   Dim f, n As Integer
  60.   For f = 0 To 6
  61.     For n = 0 To 6
  62.       If f = 3 Or n = 3 Then
  63.         workingCopyImage[x - 3 + f, y - 3 + n] = 16646144 'red
  64.         'get the zoom and scroll poistions
  65.         z = imageView1.Zoom
  66.         sx = imageview1.ScrollX
  67.         sy = imageview1.ScrollY
  68.           imageview1.Image = workingCopyImage 'reload the image
  69.           imageview1.Update()
  70.           'set the zoom and scroll positions -so the image updates but doesn't reset
  71.         imageview1.Zoom = z
  72.         imageview1.ScrollX = sx
  73.         imageview1.ScrollY = sy
  74.       Endif
  75.     Next
  76.   Next
  77.  

Any help really appreciated - I did think it might be a wayland quirk, but the same happens if I use X11.
Online now: No Back to the top

Post

Posted
Rating:
#2
Guru
BruceSteers is in the usergroup ‘Guru’
it's possibly because whenever you make an image "copy" you need to use Image.Copy()

This line is not correct, (the code does not match the comment)…
 

Code (gambas)

  1. workingCopyImage = originalImage 'copy originalImage
  2.  
With the above code workingCopyImage becomes a pointer to originalImage not a copy of it


try like this..

Code (gambas)

  1. workingCopyImage = originalImage.Copy()   ' really copy originalImage
  2.  

and do the same wherever you need a "Copy" of a Picture/Image not a pointer to it.
Online now: No Back to the top

Post

Posted
Rating:
#3
Avatar
Guru
cogier is in the usergroup ‘Guru’
Have you thought of saving the image each time a cross is added so that you can undo/redo by just changing the imageview image?
Online now: No Back to the top

Post

Posted
Rating:
#4
Regular
DIYTinkerer is in the usergroup ‘Regular’

BruceSteers said

With the above code workingCopyImage becomes a pointer to originalImage not a copy of it
try like this..

Code (gambas)

  1. workingCopyImage = originalImage.Copy()   ' really copy originalImage
  2.  

and do the same wherever you need a "Copy" of a Picture/Image not a pointer to it.

Thank you so much for the correcting and the explanation  :)
Online now: No Back to the top

Post

Posted
Rating:
#5
Regular
DIYTinkerer is in the usergroup ‘Regular’

cogier said

Have you thought of saving the image each time a cross is added so that you can undo/redo by just changing the imageview image?

I did, but it didn't feel like good practice to be using file storage like this
Online now: No Back to the top

Post

Posted
Rating:
#6
Guru
BruceSteers is in the usergroup ‘Guru’
I would probably just paste a 6x6 square from the original image over the imageview one for undoing crosses that would not overlap.
(I have not tested this so you might need to tweak it)

Code (gambas)

  1.  
  2. Public Sub undo()
  3.   Debug "Undo"
  4.   Dim X, Y As Integer
  5.   If pointIndex = 0 Then 'nothing to undo
  6.   Debug "nothing to undo"
  7.   Return 'exit sub if there's nothing to do
  8.  
  9.   Else
  10.     Debug "Copy original image area at coords directly onto the imageview image"
  11.     Debug "let's undo something"
  12.     pointIndex -= 1 'reduce point index by 1
  13.  
  14.     X = Coord[pointIndex, 0] - 3
  15.     Y = Coord[pointIndex, 1] - 3
  16.  
  17.     Paint.Begin(ImageView1.Image) ' start editing the imageview image.
  18.     Paint.DrawImage(originalImage.Copy(X, Y, 6, 6), X, Y, 6, 6)  ' Draw a 6x6 square at X, Y copied from the original.
  19.     Paint.End ' finish editing
  20.     ImageView1.Refresh  ' maybe you don't need this?
  21.   Endif
  22.  
  23.  


Ps. another tip. In your Key event you check to see if key.code = 90
It is bad practice to use code values directly because key codes can be different for QT and GTK.
you should check if Key.Text = "z" or if there is no text (like some special keys) check the Key array If Key.Code = Key["Z"]
then it will work for both QT and GTK.

Have fun :)
Online now: No Back to the top

Post

Posted
Rating:
#7
Regular
DIYTinkerer is in the usergroup ‘Regular’
thanks for the tips :-)
Online now: No Back to the top
1 guest and 0 members have just viewed this.