First define what a transparent pixel is by making a method that returns true or false. Actually, later on it’s more convenient to define what opaque is. You might want to consider certain colors or a range or something to be ‘transparent’, here it’s just anything close to Alpha 255.
Function isOpaque(c As Color) As boolean
return c.Alpha < 250
End Function
Then the trimming method just has to scan the picture and find where the first opaque pixels are from the top, bottom, left and right.
[code]Function trimPic(pic As Picture) As Picture
//init
dim surf As RGBSurface = pic.RGBSurface
dim cTop, cBottom, cLeft, cRight As integer = -1
dim x, y, xlast, ylast As integer
xlast = pic.Width - 1
ylast = pic.Height - 1
//find top
for y = 0 to ylast
for x = 0 to xlast
if isOpaque(surf.Pixel(x, y)) then
cTop = y
exit for y
end
next
next
if cTop = -1 then return nil //pic is all transparent
//find bottom
for y = ylast downto 0
for x = 0 to xlast
if isOpaque(surf.Pixel(x, y)) then
cBottom = y
exit for y
end
next
next
//find left
for x = 0 to xlast
for y = 0 to ylast
if isOpaque(surf.Pixel(x, y)) then
cLeft = x
exit for x
end
next
next
//find right
for x = xlast downto 0
for y = 0 to ylast
if isOpaque(surf.Pixel(x, y)) then
cRight = x
exit for x
end
next
next
//create cropped picture
dim result As new Picture(cRight - cLeft, cBottom - cTop)
result.Graphics.DrawPicture(srcPic, -cLeft, -cTop)
return result
End Function[/code]
This trimming algorithm isn’t very smart because the same pixel may be tested multiple times. Also there may be off-by-one errors in calculating the result width/height and/or the drawpicture offset. You’ll have to check those if you don’t find another algorithm
To test this add properties srcPic and destPic as Picture to a Window and a button with this code
[code]Sub Action()
srcPic = new Picture(300, 300)
srcPic.Graphics.ForeColor = &c00FF00
srcPic.Graphics.FillOval(47, 47, 92, 92)
srcPic.Graphics.FillOval(240, 200, 23, 23)
destPic = trimPic(srcPic)
Canvas1.Invalidate
End Sub[/code]
and a large Canvas with this Paint
[code]Sub Paint(g As Graphics, areas() As REALbasic.Rect)
if srcPic <> nil and destPic <> nil then
g.ForeColor = &c000000
g.DrawPicture srcPic, 1, 1
g.DrawRect(0, 0, srcPic.Width+2, srcPic.Height+2)
g.DrawPicture destPic, 1, srcPic.Height+9
g.DrawRect(0, srcPic.Height+8, destPic.Width+2, destPic.Height+2)
end
End Sub[/code]