Anything beyond the basics in using the LiveCode language. Share your handlers, functions and magic here.
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller
-
jmburnod
- VIP Livecode Opensource Backer

- Posts: 2729
- Joined: Sat Dec 22, 2007 5:35 pm
-
Contact:
Post
by jmburnod » Sun May 17, 2009 6:30 pm
Hi All,
I want know the top of a paint image (the first pixel with a color <> "255,255,255")
I try a method by the mousecolor function like that :
Code: Select all
on tTopOfpaint n -- (n= short name of an image)
put the ticks into old
put the rect of image n into Lar
put item 1 of LaR into LaG
put item 3 of LaR into LaD
put item 2 of LaR into LeT
put item 4 of Lar into LeB
put 0 into bufTop
repeat until bufTop <> 0
repeat with i = LaG to LaD
put i & "," &LeT into LeP
set the screenMouseLoc to globalLoc(LeP)
put the mousecolor into LaMC
wait 1 milliseconds -- to watch the progress
if LaMC <> "255,255,255" then
put LeP&LaMC &return into bufTop
choose browse tool
dansmes LeT&& the ticks - old
exit tTopOfpaint
end if
end repeat
add 1 to LeT
end repeat
end tTopOfpaint
on DansMes t
put t
end DansMes
I think someone know a better way.
Thanks for your comments
Jean-Marc
-
Janschenkel
- VIP Livecode Opensource Backer

- Posts: 977
- Joined: Sat Apr 08, 2006 7:47 am
-
Contact:
Post
by Janschenkel » Mon May 18, 2009 6:27 am
This approach would only work if nothing was overlapping the image - including other application windows. You're better off looking at the
imageData property of the image control.
Code: Select all
function TopOfPaint pImage
put the imageData of image pImage into tImageData
put the width of image pImage into tWidth
put the height of image pImage into tHeight
put empty into tTopBuffer
put 1 into tByteIndex
put binaryEncode("CCCC",0,255,255,255) into tComparePixelData
repeat with tRow = 1 to tHeight
repeat with tColumn = 1 to tWidth
put byte tByteIndex to tByteIndex + 3 of tImageData into tPixelData
if tPixelData is not tComparePixelData then
local tAlpha, tGreen, tRed, tBlue
get binaryDecode("CCCC",tPixelData,tAlpha,tRed,tGreen,tBlue)
put tRow, tColumn, tRed, tGreen, tBlue into tTopBuffer
return tTopBuffer
end if
end repeat
end repeat
return empty
end TopOfPaint
Not tested but it should be pretty close.
HTH,
Jan Schenkel.
-
jmburnod
- VIP Livecode Opensource Backer

- Posts: 2729
- Joined: Sat Dec 22, 2007 5:35 pm
-
Contact:
Post
by jmburnod » Mon May 18, 2009 8:48 am
Thanks Jan,
Yes, the approach by mousecolor dont work if an other object is over the image.
I'm not again friendly with imagedata, by i think it is a better way and your comment help me to know it
I tested your TopOfpaint one time :
The result is empty for my image
(a simple line black made with the brush)
Jean-Marc
-
Janschenkel
- VIP Livecode Opensource Backer

- Posts: 977
- Joined: Sat Apr 08, 2006 7:47 am
-
Contact:
Post
by Janschenkel » Tue May 19, 2009 5:22 am
I think I found the culprit: I forgot to increment the tByteOffset variable.
Code: Select all
function TopOfPaint pImage
put the imageData of image pImage into tImageData
put the width of image pImage into tWidth
put the height of image pImage into tHeight
put empty into tTopBuffer
put 1 into tByteIndex
put binaryEncode("CCCC",0,255,255,255) into tComparePixelData
repeat with tRow = 1 to tHeight
repeat with tColumn = 1 to tWidth
put byte tByteIndex to tByteIndex + 3 of tImageData into tPixelData
if tPixelData is not tComparePixelData then
local tAlpha, tGreen, tRed, tBlue
get binaryDecode("CCCC",tPixelData,tAlpha,tRed,tGreen,tBlue)
put tRow, tColumn, tRed, tGreen, tBlue into tTopBuffer
return tTopBuffer
end if
add 4 to tByteOffset
end repeat
end repeat
return empty
end TopOfPaint
That ought to do the trick.
Jan Schenkel.
-
jmburnod
- VIP Livecode Opensource Backer

- Posts: 2729
- Joined: Sat Dec 22, 2007 5:35 pm
-
Contact:
Post
by jmburnod » Tue May 19, 2009 9:23 am
Hi Jan,
If you increment tByteindex and not tByteOffset

TopOfPaint return the color of the first pixel <> 255,255,255 but not the location of the pixel (tRow and tColumn still = 1)
Code: Select all
function TopOfPaint pImage
put the imageData of image pImage into tImageData
put the width of image pImage into tWidth
put the height of image pImage into tHeight
put empty into tTopBuffer
put 1 into tByteIndex
put binaryEncode("CCCC",0,255,255,255) into tComparePixelData
repeat with tRow = 1 to tHeight
repeat with tColumn = 1 to tWidth
put byte tByteIndex to tByteIndex + 3 of tImageData into tPixelData
if tPixelData is not tComparePixelData then
local tAlpha, tGreen, tRed, tBlue
get binaryDecode("CCCC",tPixelData,tAlpha,tRed,tGreen,tBlue)
put tRow, tColumn, tRed, tGreen, tBlue into tTopBuffer
return tTopBuffer
end if
add 4 to tByteIndex
end repeat
end repeat
return empty
end TopOfPaint
All the best
Jean-Marc
-
Janschenkel
- VIP Livecode Opensource Backer

- Posts: 977
- Joined: Sat Apr 08, 2006 7:47 am
-
Contact:
Post
by Janschenkel » Tue May 19, 2009 8:40 pm
Aargh, silly computer - do as I think, not as I say

You're right, I meant to increment tByteIndex; however, in my tests, it does return the row and column correctly. You can always set a breakpoint and debug to see what's in there when it has found a different color.
Jan Schenkel.
-
jmburnod
- VIP Livecode Opensource Backer

- Posts: 2729
- Joined: Sat Dec 22, 2007 5:35 pm
-
Contact:
Post
by jmburnod » Tue May 19, 2009 10:30 pm
YES jan,
I have an explanation for the result 1,1 for "tRow, tColumn,".
I confused white pixel and transparent pixel
TopOfPaint work well but if i want the first pixel <> transparent i need the number of transparent color.
I search in the doc but if found nothing (at the moment...)
many thanks for your help
Jean-Marc
-
Janschenkel
- VIP Livecode Opensource Backer

- Posts: 977
- Joined: Sat Apr 08, 2006 7:47 am
-
Contact:
Post
by Janschenkel » Wed May 20, 2009 5:42 am
In that case, you need to work with the alphaData property as well.
Whereas the imageData is comprised of 4 bytres per pixel, the alphaData is just one byte per pixel, so you can create a similar loop.
Jan Schenkel.
-
jmburnod
- VIP Livecode Opensource Backer

- Posts: 2729
- Joined: Sat Dec 22, 2007 5:35 pm
-
Contact:
Post
by jmburnod » Wed May 20, 2009 10:12 am
Yes one more Jan,
It work fine and very fast
Code: Select all
-- the location of the first (top) pixel no transparent of an image. 0,0 = the topleft of the image
function TopOfPaintAlpha pImage
put the alphadata of image pImage into tAlphaData
put the width of image pImage into tWidth
put the height of image pImage into tHeight
put empty into tTopBuffer
put 1 into tByteIndex
repeat with tRow = 1 to tHeight
repeat with tColumn = 1 to tWidth
put charToNum(char tByteIndex of tAlphaData) into tPixelData
if tPixelData is not 0 then
put tRow, tColumn into tTopBuffer
return tTopBuffer
end if
add 1 to tByteIndex
end repeat
end repeat
return empty
end TopOfPaintAlpha
Jean-Marc
-
bn
- VIP Livecode Opensource Backer

- Posts: 4174
- Joined: Sun Jan 07, 2007 9:12 pm
Post
by bn » Wed May 20, 2009 11:37 am
Jean-Marc,
if you are working with images the alphadata can go from 0 to 255 to give shades of transparencies. If you want an index of complete transparency versus complete opacity the maskData gives you either 0 or 255, without the intermediate values of the alphaData. At times that can be useful. Otherwise the maskData is similar to the alphaData, one byte for each pixel.
regards
Bernd