Copy, Rotate and Save Transparent PNG?

I am attempting to create a method that accepts a transparent png image and a rotation (45, 90, 180) and returns a rotated transparent image of the original image.

I first tried this code from the Language Reference and modified it slightly to correctly draw a oval whose outer edges touch the top and left edge of the main window.

  Dim p as Picture
  Dim px as PixmapShape
  p=New Picture(240,200,32)
  p.graphics.foreColor = &cFF0000
  p.graphics.fillOval 0,0,240,200
  px=New PixmapShape(p)
  px.rotation = 90/57.2958  //90 Degrees in radians
  Graphics.drawObject px,p.height/2,p.width/2

The code below causes the IDE to display a message box “The application has encountered a problem…”. When I tell the IDE to quit the line “RotatedP.Graphics.DrawObject PX, P.Height, P.Width” is highlighted.

Function RotatePic(P as Picture, Rotate as Integer) As Picture
  Dim PX as PixMapShape
  Dim RotatedP as Picture
  Dim CenterX, CenterY as Integer
  
  RotatedP = New Picture(P.Height, P.Width, 32)
  CenterX = P.Height / 2
  CenterY = P.Width / 2
  PX = New PixMapShape(P)
  PX.Rotation = Rotate/57.2958
  RotatedP.Graphics.DrawObject PX, P.Height, P.Width
  Return RotatedP
End Function

I also found the following code from Thomas Ree, which does work, but it returns a image with a white background and I need to maintain the transparent pixels from the original image.

http://computer-programming-forum.com/14-realbasic/d5ff9d0494e0c62e.htm

 // Rotates the given picture in increments of 90 degrees.

  dim source, dest as Picture
  dim sourcePixels, destPixels as RGBSurface
  dim rType,x,y,w,h,we,he as integer

  w = pictToRotate.width
  h = pictToRotate.height

  if pictToRotate = nil then
    return nil
  end if
  if pictToRotate.RGBSurface = nil then
    source = NewPicture(pictToRotate.width, pictToRotate.height, 32)
    if source = nil then
      return nil
    end if
    source.Graphics.DrawPicture pictToRotate, 0, 0
  else
    source = pictToRotate
  end if

  // rType tells how to rotate: 0=none, 1=90 CW, 2=180 CW, 3=270 CW
  if angle = 0 then
    return source
  elseif angle = 90 or angle = -270 then
    rType = 1
  elseif angle = 180 or angle = -180 then
    rType = 2
  elseif angle = 270 or angle = -90 then
    rType = 3
  else
    return nil
  end if

  if rType = 1 or rType = 3 then
    dest = NewPicture(h, w, 32)
  else
    dest = NewPicture(w, h, 32)
  end if
  if dest = nil then
    return nil
  end if

  sourcePixels = source.RGBSurface
  destPixels = dest.RGBSurface
  if sourcePixels = nil or destPixels = nil then
    return nil
  end if

  we = w-1
  he = h-1
  for x = 0 to we
    for y = 0 to he
      if rType = 1 then
        destPixels.Pixel(h-y,x) = sourcePixels.Pixel(x,y)
      elseif rType = 2 then
        destPixels.Pixel(w-x,h-y) = sourcePixels.Pixel(x,y)
      else // rType must be 3
        destPixels.Pixel(y,w-x) = sourcePixels.Pixel(x,y)
      end if
    next
  next

  return dest
End Function 

Don’t include the 32. This creates a masked picture while leaving it off creates an alpha channeled picture.

Same thing in Thomas Ree’s code. Or you may want to handle both masked and alpha channel pictures.

I’m not sure. Is the passed in picture P nil?