Link to home
Start Free TrialLog in
Avatar of icredes
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
Avatar of Erick37
Erick37
Flag of United States of America image

How does the image get to the picturebox?
Are you passed any info about the image dimensions?
Avatar of icredes
icredes

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?
Avatar of icredes

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.
Avatar of icredes

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.
ASKER CERTIFIED SOLUTION
Avatar of Erick37
Erick37
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@ 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\Desktop\LAPTOP.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
Avatar of inthedark
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:\........jpg")
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
Avatar of icredes

ASKER

Erick37  you nailed it

that works great for me...thanks