Page 1 of 1

Pixel processing in SP6

Posted: 29 Mar 2021, 03:28
by fabdev
Hello, as written in the post about the release of Service Pack 6, some new commands have been added, and all the "GetPixel" and "SetPixel" commands are now much faster to permit image processing and analysis in scripts.

Image.PrepareUndo
Image.Undo
Image.GetPixelR(x,y)
Image.GetPixelG(x,y)
Image.GetPixelB(x,y)
Image.SetPixelRGB(x,y,r,g,b)


"Image.PrepareUndo" stores the current image in the Undo buffer. Try for example on a grayscale image: (on a color image it will process only the green plane)

Code: Select all

Image.PrepareUndo
cx = Image.Width
cy = Image.Height
x1 = Round(cx * 0.25)
y1 = Round(cy * 0.25)
x2 = Round(cx * 0.75)
y2 = Round(cy * 0.75)
for y = y1 to y2 
  for x = x1 to x2
    v = Image.GetPixel(x,y)
    Image.SetPixel(x,y,v*1.05)
  next x
next y  
Image.Update
Pause(2)
Image.Undo
The typical speed is approx 1 megapixel/sec for such filters. If you need to work on a multi-megapixel image you may consider implementing a preview in a selected rectangle:

Code: Select all

Image.PrepareUndo
x1 = Image.Rectangle.X1
y1 = Image.Rectangle.Y1
x2 = Image.Rectangle.X2
y2 = Image.Rectangle.Y2
if x1 = x2 then
  Message("Please select a rectangle")
  end
end if
for y = y1 to y2
 for x = x1 to x2
   v = Image.GetPixel(x,y)
   Image.SetPixel(x,y,v*1.05)
 next x
next y
Image.Update
or a mask (grayscale example):

Code: Select all

Image.PrepareUndo
if not Image.Mask.Active then
  Message("Please select a mask")
  end
end if
x1 = Image.Mask.X1
y1 = Image.Mask.Y1
x2 = Image.Mask.X2
y2 = Image.Mask.Y2
for y = y1 to y2
 for x = x1 to x2
   m = Image.Mask.GetPixel(x,y)
   if m <= 0.5 then continue
   v = Image.GetPixel(x,y)
   Image.SetPixel(x,y,v*1.05*m)
 next x
next y
Image.Update
smoothed mask: (grayscale)

Code: Select all

Image.PrepareUndo
if not Image.Mask.Active then
  Message("Please select a mask")
  end
end if
x1 = Image.Mask.X1
y1 = Image.Mask.Y1
x2 = Image.Mask.X2
y2 = Image.Mask.Y2
for y = y1 to y2
 for x = x1 to x2
   m = Image.Mask.GetPixel(x,y)
   if m <= 0 then continue
   vOri = Image.GetPixel(x,y)
   vNew = vOri*1.1
   v = vNew*m + vOri*(1-m)
   Image.SetPixel(x, y, v)
 next x
next y
Image.Update
use the commands GetPixelR, G, B to process a color image. For example: (desaturation)

Code: Select all

Image.PrepareUndo
x1 = Image.Rectangle.X1
y1 = Image.Rectangle.Y1
x2 = Image.Rectangle.X2
y2 = Image.Rectangle.Y2
if x1 = x2 then
  Message("Please select a rectangle")
  end
end if
for y = y1 to y2
 for x = x1 to x2
   r = Image.GetPixelR(x,y) 
   g = Image.GetPixelG(x,y)
   b = Image.GetPixelB(x,y)
   lum = r*0.3 + g*0.6 + b*0.1
   Image.SetPixel(x, y, (r+lum)*0.5, (g+lum)*0.5, (b+lum)*0.5)
 next x
next y
Image.Update

Re: Pixel processing in SP6

Posted: 11 May 2021, 14:25
by Rudi
Hi Fabio,

This is great.

Is it possible to define a two dimensional array in the scripting language?
I've tried: dim(640,480) dim(640;480) dim(640:480) dim(640)(480) (...and many more), but with no luck.

I need to store the image bits in an array in order to subtract one image from another in a script.

Re: Pixel processing in SP6

Posted: 12 May 2021, 14:10
by fabdev
Hi Rudi,
it's not possible, but just like in C it's possible to use a mono-dimensional array to represent the image, then the item can be addressed as X + Y*Width . For example for coordinate x = 100 and y = 50:

w = 640
h = 480
Dim arr(w*h)
x = 100
y = 50
arr(x + y*w + 1) = 65000
print arr(x + y*w + 1)

Every array item will take 32 bytes by the way.

to subtract a given image to several images via scripts it's also possible to use: Image.Macro(1) , after having defined the Macro #1 as Subtract Image.

Re: Pixel processing in SP6

Posted: 13 May 2021, 04:05
by Rudi
Thanks Fabio. I will proceed with the one dimensional array. Just wanted to ask first ;-)