Pixel Level Data
Moderator: Kathy_9
-
- Posts: 12
- Joined: Tue Dec 18, 2018 6:38 am
- System_Drive: C
- 32bit or 64bit: 64 Bit
- Corel programs: PSP 2019 Ultimate
Pixel Level Data
Is it possible to get access to pixel-level-data through the API. I.e. traverse the array of pixels and access attributes such as color, transparency, or whether it is within a selection?
-
- Advisor
- Posts: 6777
- Joined: Thu Oct 02, 2008 1:07 pm
- System_Drive: C
- 32bit or 64bit: 64 Bit
- motherboard: Alienware M17xR4
- processor: Intel Core i7-3630QM CPU - 2_40GH
- ram: 6 GB
- Video Card: NVIDIA GeForce GTX 660M
- sound_card: Sound Blaster Recon3Di
- Hard_Drive_Capacity: 500GB
- Corel programs: PSP: 8-2023
- Location: USA
Re: Pixel Level Data
No, and kind of yes.
In the strictest sense, no it's not possible. PSP offers no ability to get pixel level data. Much less any of its attributes. However, it is still possible to do what you want on at least some level.
For example, we cannot get the color of a pixel directly, what we have to do is use the eye-dropper to sample the color, and then we can use 'GetMaterial' to get the value of the currently selected material from the materials palette. At the same time, however, since the materials palette doesn't support transparency in normal color selection we cannot find out the transparency value of a pixel.
Here is a simple function that first saves your current material, samples a material from the image, grabs the color, then resets the material to defaults.
I'm not sure how to grab the transparency of a pixel though. For transparency I suppose one could put a temporary layer underneath the pixel of a known color. Sample the normal color and the merged result with the eye-dropper and see how much the alpha played a roll in the math. I don't know the full math details myself, and I suck at math, so not entirely sure how that works but it would be one of the easiest ways.
Checking if a pixel is inside a selection is a bit harder, though not too hard. We can grab some basic information about a selection, like what kind of selection it is (raster, vector, floating, no selection at all) and where it starts and how big it is. We can also perform functions like editing the selection. So using these tools I can remove all of a selection around a single pixel and then test if a selection still exists. If it does, then that pixel was inside of a selection. If it's not then the pixel was not inside of a selection. And, of course, we restore the original selection at the end so we're back where we started from.
In the strictest sense, no it's not possible. PSP offers no ability to get pixel level data. Much less any of its attributes. However, it is still possible to do what you want on at least some level.
For example, we cannot get the color of a pixel directly, what we have to do is use the eye-dropper to sample the color, and then we can use 'GetMaterial' to get the value of the currently selected material from the materials palette. At the same time, however, since the materials palette doesn't support transparency in normal color selection we cannot find out the transparency value of a pixel.
Here is a simple function that first saves your current material, samples a material from the image, grabs the color, then resets the material to defaults.
Code: Select all
def getColor(Environment, x, y):
Material = App.Do( Environment, 'GetMaterial', { 'IsPrimary': True }) #Gets current material before using eye-dropper
App.Do( Environment, 'Eyedropper', {'Point': (x,y), 'SampleSize': 0, 'Material': App.Constants.MaterialRef.Foreground, 'ActiveLayerOnly': True, 'SampleColor': 0, }) #sample color
color = App.Do( Environment, 'GetMaterial', { 'IsPrimary': True })['Color']
App.Do( Environment, 'SetMaterial', { 'IsPrimary': True, 'NewMaterial':Material }) #Resets original material
return color
Checking if a pixel is inside a selection is a bit harder, though not too hard. We can grab some basic information about a selection, like what kind of selection it is (raster, vector, floating, no selection at all) and where it starts and how big it is. We can also perform functions like editing the selection. So using these tools I can remove all of a selection around a single pixel and then test if a selection still exists. If it does, then that pixel was inside of a selection. If it's not then the pixel was not inside of a selection. And, of course, we restore the original selection at the end so we're back where we started from.
Code: Select all
from PSPApp import *
from PSPUtils import *
def ScriptProperties():
return {
'Author': u'',
'Copyright': u'',
'Description': u'',
'Host': u'PaintShop Pro',
'Host Version': u'22.00'
}
def Do(Environment):
# EnableOptimizedScriptUndo
App.Do( Environment, 'EnableOptimizedScriptUndo', {'GeneralSettings': {}})
print pointInSelection(Environment, 1127,505)
print pointInSelection(Environment, 1128,505)
def pointInSelection(Environment, x, y, doc = App.TargetDocument):
# '''This command removes giant rectangels around the selected point.
# if a selection still exists then the point was inside the selection
# however, if no selection exists, then the point was outside the selection'''
#save original selection to get it back later
selection = SaveSelection(Environment, doc)
#restore selection
selection.RestoreSelection()
#get current selection rectangle
Rect = App.Do( Environment, 'GetRasterSelectionRect' )
#Convert Rect to full point values
Rect = [Rect['Rect'][0][0], Rect['Rect'][0][1], Rect['Rect'][1]+Rect['Rect'][0][0],Rect['Rect'][2]+Rect['Rect'][0][1]]
if x < Rect[0] or x > Rect[2] or y < Rect[1] or y > Rect[3]: #if point is outside selection rectangle, point is not in selection
return False
#remove all of the selections around the point
removeRectFromSelection(Environment, Rect[0],Rect[1], x, Rect[3]) #Left |
removeRectFromSelection(Environment, Rect[0],Rect[1], Rect[2], y) #Top --
removeRectFromSelection(Environment, x+1,Rect[1], Rect[2], Rect[3]) #Right |
removeRectFromSelection(Environment, Rect[0],y+1, Rect[2], Rect[3]) #Bottom__
#check for selection
Rect = App.Do( Environment, 'GetRasterSelectionRect' )
#restore original seleciton
selection.RestoreSelection()
#return False if no selection remains, otherwise True
return False if Rect['Type'] == 0 else True
def removeRectFromSelection(Environment, x, y,x2,y2):
# Selection
App.Do( Environment, 'Selection', {
'General': {'Mode': App.Constants.SelectionOperation.Remove, 'Antialias': False, 'Feather': 0},
'SelectionShape': App.Constants.SelectionShape.Rectangle,
'Start': (x,y),
'End': (x2,y2),
'SelectionStyle': App.Constants.SelectionStyle.Normal,
'GeneralSettings': {}
})
-
- Posts: 12
- Joined: Tue Dec 18, 2018 6:38 am
- System_Drive: C
- 32bit or 64bit: 64 Bit
- Corel programs: PSP 2019 Ultimate
Re: Pixel Level Data
Thank you for these solutions. They are very good. I had figured the eyedropper/getmaterial was a path, but in my testing it is very slow (primarily when the sampled color changes). But thanks for confirming that there really isn't a better way.
I like your approach with the selection. I had gone down a route of flood filling inside and outside the selection with different colors and then sampling (with the method above). This worked okay, but relied on the assumption of being able to fill the selection from the center of the GetRasterSelectionRect. I like your method better for finding selection pixels. It will work regardless of the shape of the selection.
Thanks again, and for such a quick response.
I like your approach with the selection. I had gone down a route of flood filling inside and outside the selection with different colors and then sampling (with the method above). This worked okay, but relied on the assumption of being able to fill the selection from the center of the GetRasterSelectionRect. I like your method better for finding selection pixels. It will work regardless of the shape of the selection.
Thanks again, and for such a quick response.
-
- Advisor
- Posts: 6777
- Joined: Thu Oct 02, 2008 1:07 pm
- System_Drive: C
- 32bit or 64bit: 64 Bit
- motherboard: Alienware M17xR4
- processor: Intel Core i7-3630QM CPU - 2_40GH
- ram: 6 GB
- Video Card: NVIDIA GeForce GTX 660M
- sound_card: Sound Blaster Recon3Di
- Hard_Drive_Capacity: 500GB
- Corel programs: PSP: 8-2023
- Location: USA
Re: Pixel Level Data
Cassel here on the forums has a great method for finding the first pixel location in a selection. She's an excellent source for getting PSP to do fancy things, in my opinion.
What happens is she modifies the selection and removes all but the first row of selected pixels. The result is that the starting point of the selection is now also guaranteed to be the very first pixel in the selection. Just grab that location and you can use it with the fill tool to ensure you're always filling the selection.
What happens is she modifies the selection and removes all but the first row of selected pixels. The result is that the starting point of the selection is now also guaranteed to be the very first pixel in the selection. Just grab that location and you can use it with the fill tool to ensure you're always filling the selection.
-
- Posts: 12
- Joined: Tue Dec 18, 2018 6:38 am
- System_Drive: C
- 32bit or 64bit: 64 Bit
- Corel programs: PSP 2019 Ultimate
Re: Pixel Level Data
Sounds like a very useful method.
-
- Posts: 1
- Joined: Sat Apr 25, 2020 10:41 am
- System_Drive: C
- 32bit or 64bit: 64 Bit
Re: Pixel Level Data
To speed up the mentioned method of picking each pixel with the eyedropper by a thousand fold make sure your materials "pallet" is not shown.
-
- Posts: 63
- Joined: Sun Apr 28, 2019 12:26 pm
- System_Drive: C
- 32bit or 64bit: 64 Bit
- Corel programs: PaintShop PRO 2019 32bit
Re: Pixel Level Data
Hi to all,
sorry for the probably stupi question but in the examples above I have seen:
selection = SaveSelection(Environment, doc)
and
selection.RestoreSelection
I suppose that SaveSelection and RestoreSelection are correlated with PSPutils ... but please, where can I find references for PSPutils ?
Thank you in advance.
Paolo
sorry for the probably stupi question but in the examples above I have seen:
selection = SaveSelection(Environment, doc)
and
selection.RestoreSelection
I suppose that SaveSelection and RestoreSelection are correlated with PSPutils ... but please, where can I find references for PSPutils ?
Thank you in advance.
Paolo
-
- Advisor
- Posts: 6777
- Joined: Thu Oct 02, 2008 1:07 pm
- System_Drive: C
- 32bit or 64bit: 64 Bit
- motherboard: Alienware M17xR4
- processor: Intel Core i7-3630QM CPU - 2_40GH
- ram: 6 GB
- Video Card: NVIDIA GeForce GTX 660M
- sound_card: Sound Blaster Recon3Di
- Hard_Drive_Capacity: 500GB
- Corel programs: PSP: 8-2023
- Location: USA
Re: Pixel Level Data
The Scripting For Script Authors PDF (listed in the Scripting Resources topic at the top of the Scripting board) covers most if not all of the PSPUtils library.
-
- Posts: 63
- Joined: Sun Apr 28, 2019 12:26 pm
- System_Drive: C
- 32bit or 64bit: 64 Bit
- Corel programs: PaintShop PRO 2019 32bit
Re: Pixel Level Data
Many thanks 
.