icredes
asked on
reading jpg image pixel values
OK, here is what I have...
I have a program that scans via twain image driver.
We have what is called a routing slip similar to a scantron where people are coloring in circles.
I want to be able to read pixel values from any point. because we are scanning at such a high resolution the image goes outside of the visible picture box.
my problem is that I cannot read any part of an image that is not visible in a picture box.
my goal is to read pixel rgb values given an x,y coordinate in pixels for any point in the image without dealing with a picture box or external dll objects.
we are using this object as an activeX web object.
Thank you so much for all your help
I have a program that scans via twain image driver.
We have what is called a routing slip similar to a scantron where people are coloring in circles.
I want to be able to read pixel values from any point. because we are scanning at such a high resolution the image goes outside of the visible picture box.
my problem is that I cannot read any part of an image that is not visible in a picture box.
my goal is to read pixel rgb values given an x,y coordinate in pixels for any point in the image without dealing with a picture box or external dll objects.
we are using this object as an activeX web object.
Thank you so much for all your help
ASKER
the only information that I have is the file path
I assume the image is hidden, though, yes? Why not set the Picturebox AutoSize property to True?
ASKER
the issue is that I need to be able to view the image at 100% 300 dpi
getting the image dimentions is not too difficult.
my concern is getting the pixel values
I am going to assume that the image is the correct size.
getting the image dimentions is not too difficult.
my concern is getting the pixel values
I am going to assume that the image is the correct size.
ASKER
the autosize feature is interesting, but the point here is not to use the picture box
even if I get the correct size, the image is too big to fit on the screen.
is there another way....
lets assume that I were to do this in a module without the use of a form if possible.
even if I get the correct size, the image is too big to fit on the screen.
is there another way....
lets assume that I were to do this in a module without the use of a form if possible.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
@ icredes
The following program needs a source Picbox(no matter if visible or invisible) and a destination picbox(visible).
It works without API. You will get all the r-g-b values of the picture and of each pixel.
Form1:
----------------
'Needs 2 Pictureboxes
Const Pic = "C:\WINDOWS\Desktop\LAPTOP .JPG"
Private Sub Form_Activate()
AutoRedraw = -1: Picture2.ScaleMode = 3
Move 0, 0: Picture1.BackColor = vbBlue
Picture1.Move 15 * 70, 15 * 15, 15 * 360, 15 * 290
Picture1.BorderStyle = 0: Picture1.ScaleMode = 3
Picture2.BorderStyle = 0: Picture1.BackColor = vbWhite: Picture2.BackColor = vbWhite
Picture2.Move Picture1.Left + Picture1.Width + 15 * 9, 15 * 15, 15 * 30, 15 * 18
DoEvents
Picture1.Picture = LoadPicture("C:\WINDOWS\De sktop\LAPT OP.JPG")
For YY = 0 To Picture1.Picture.Width
For XX = 0 To Picture1.Picture.Height
Picture2.PaintPicture Picture1.Picture, 0, 0, 1, 1, XX, YY, 1, 1
DoEvents
col = Picture2.Point(0, 0) 'BGR
Picture2.BackColor = col
b = (col And 16711680) / 65536 ' 16711680 = FF0000
g = (col And 65280) / 256 ' 65280 = FF00
r = col And 255
MsgBox XX & " , " & YY & vbCrLf _
& "r , g , b" & vbCrLf & r & " , " & g & " , " & b
Next
Next: End
End Sub
The following program needs a source Picbox(no matter if visible or invisible) and a destination picbox(visible).
It works without API. You will get all the r-g-b values of the picture and of each pixel.
Form1:
----------------
'Needs 2 Pictureboxes
Const Pic = "C:\WINDOWS\Desktop\LAPTOP
Private Sub Form_Activate()
AutoRedraw = -1: Picture2.ScaleMode = 3
Move 0, 0: Picture1.BackColor = vbBlue
Picture1.Move 15 * 70, 15 * 15, 15 * 360, 15 * 290
Picture1.BorderStyle = 0: Picture1.ScaleMode = 3
Picture2.BorderStyle = 0: Picture1.BackColor = vbWhite: Picture2.BackColor = vbWhite
Picture2.Move Picture1.Left + Picture1.Width + 15 * 9, 15 * 15, 15 * 30, 15 * 18
DoEvents
Picture1.Picture = LoadPicture("C:\WINDOWS\De
For YY = 0 To Picture1.Picture.Width
For XX = 0 To Picture1.Picture.Height
Picture2.PaintPicture Picture1.Picture, 0, 0, 1, 1, XX, YY, 1, 1
DoEvents
col = Picture2.Point(0, 0) 'BGR
Picture2.BackColor = col
b = (col And 16711680) / 65536 ' 16711680 = FF0000
g = (col And 65280) / 256 ' 65280 = FF00
r = col And 255
MsgBox XX & " , " & YY & vbCrLf _
& "r , g , b" & vbCrLf & r & " , " & g & " , " & b
Next
Next: End
End Sub
I found a good way to do this. What it does is map an array's memory to point to a picture's memory. But the cute thing is that you map a UDT array so that you don't have to do any maths to get the pixel values. This makes it very fast.
I took the concept from here:
http://www.visualbasicforum.com/t25347.html
(Also search goolge for safearray2d for more inhfo/examples like the same.
And then made the leap into using a UDT array. You can either use a 2 dimensional array, or in some cases for faster image processing, you can use a single dimensional array.
I renamed the class zPicArray, so for example:
Dim PA as zPicArray
Set picAnyPic.Picture = LoadPicture("C:\........jp g")
Set PA = New zPicArray
PA.LoadImage picAnyPic
Pa.ProcessImage Actions.ConvertToGreyScale
' extract from the class (single dimension version) the following converts a colour image to greay scale
Sub ProccessImage(Action As Actions)
Dim cp As Long
Dim Av As Long
Dim bt As Byte
Dim GreyFactor As Single
GreyFactor = 0.333333
cp = 0
Select Case Action
Case Is = Actions.ConvertToGreyScale
' loop through image
Do While cp < aSize ' asize is the size of the pic in pixels
Av = (0& + Data(cp).Red + Data(cp).Green + Data(cp).Blue) * GreyFactor
bt = Av
' Save the greyed pixel values back into the picture box
Data(cp).Red = bt
Data(cp).Green = bt
Data(cp).Blue = bt
cp = cp + 1
Loop
End Select
End Sub
In you case you may wish to stay with 2 dim array. So to modify the example from visualbasicforum to use UDT's you need:
Private Type PixelDef
Blue As Byte
Green As Byte
Red As Byte
End Type
Private Data() As PixelDef ' was byte
And in the LoadImage sub change
.cbElements = 3 ' was 1 to point to a byte
If you need any more info with this concept.
I took the concept from here:
http://www.visualbasicforum.com/t25347.html
(Also search goolge for safearray2d for more inhfo/examples like the same.
And then made the leap into using a UDT array. You can either use a 2 dimensional array, or in some cases for faster image processing, you can use a single dimensional array.
I renamed the class zPicArray, so for example:
Dim PA as zPicArray
Set picAnyPic.Picture = LoadPicture("C:\........jp
Set PA = New zPicArray
PA.LoadImage picAnyPic
Pa.ProcessImage Actions.ConvertToGreyScale
' extract from the class (single dimension version) the following converts a colour image to greay scale
Sub ProccessImage(Action As Actions)
Dim cp As Long
Dim Av As Long
Dim bt As Byte
Dim GreyFactor As Single
GreyFactor = 0.333333
cp = 0
Select Case Action
Case Is = Actions.ConvertToGreyScale
' loop through image
Do While cp < aSize ' asize is the size of the pic in pixels
Av = (0& + Data(cp).Red + Data(cp).Green + Data(cp).Blue) * GreyFactor
bt = Av
' Save the greyed pixel values back into the picture box
Data(cp).Red = bt
Data(cp).Green = bt
Data(cp).Blue = bt
cp = cp + 1
Loop
End Select
End Sub
In you case you may wish to stay with 2 dim array. So to modify the example from visualbasicforum to use UDT's you need:
Private Type PixelDef
Blue As Byte
Green As Byte
Red As Byte
End Type
Private Data() As PixelDef ' was byte
And in the LoadImage sub change
.cbElements = 3 ' was 1 to point to a byte
If you need any more info with this concept.
And also in the loadimage change:
.Bounds(1).cElements = BMP.bmWidthBytes
To
.Bounds(1).cElements = BMP.bmWidth
So after your loadimage you can then loop image. I posted a single dim example, here is a 2 dim example of looping through an image:
' filter out red
For y = 0 To mvarUBoundY
For x = 0 To mvarUBoundX
Datal(x,y).Red = 0
Next
Next
.Bounds(1).cElements = BMP.bmWidthBytes
To
.Bounds(1).cElements = BMP.bmWidth
So after your loadimage you can then loop image. I posted a single dim example, here is a 2 dim example of looping through an image:
' filter out red
For y = 0 To mvarUBoundY
For x = 0 To mvarUBoundX
Datal(x,y).Red = 0
Next
Next
ASKER
Erick37 you nailed it
that works great for me...thanks
that works great for me...thanks
Are you passed any info about the image dimensions?