Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations John Tel on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Excel pixel addressing? 1

Status
Not open for further replies.

N1GHTEYES

Technical User
Jun 18, 2004
771
GB
I'd like to be able to address pixels on an image on a userform, in Excel, either direct on the form, or via an image control. Ideally, I'd like to be able to write to them, but even reading would be a start.

The ideal way would be via the kind of functionality offered by the pset method of pictureboxes in VB. I know the image control is not a picturebox, but does anyone know of some other control (accessible from a "standard" installation of Office) which would do the job?

I'd even be happy if I could just find a control with an hwnd property, so I could do the addressing by setbitmapbits and getbitmapbits using the API. But neither the userform, nor the image control have hwnd.

Normally, I'd do this kind of stuff in VB, but a few other users would like to use the functionality I'm trying to create, and our PC's are locked down so damned tight that sorting out the paperwork for installing user-created apps is a herculean task. If I can find a way of doing it in plain old excel (or by calling an object everyone has access to by default), that would be much easier.

All suggestions gratefully received...

Tony
 
>But neither the userform, nor the image control have hwnd

They do - they're just not exposed by the Forms 2 library. You just need to use the FindWindow API call to get the hWnd. Assuming your userform is called UserForm1:

Option Explicit

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long

Private Sub CommandButton1_Click()
MsgBox FindWindow("ThunderDFrame", "UserForm1")
End Sub
 
Strongm - what a star you are - so have one.

I assume that the output of the Findwindow function is the hwnd itself, but perhaps you could clarify a couple of points though?

I may just be a little slow this evening, but what, exactly is the purpose of the "ThunderDFrame" argument? And do I not have to do anything to reference the app of which userform1 is a part?

Thanks,
Tony
 
ThunderDFrame" is the class name of the Forms 2.0 form; using it in the call just helps ensure we don't get just any old window called UserForm1 ...

And no, you don't have to do anything to reference the app. Of course if there are likely to be a number of spreadsheets open with their own forms called UserForm1 then what you might want to do is rename your form to something tending towards the unique, and then the "UserForm1" in the API call to whatever yoiu've called your form
 
Triffic. Should do the job nicely.

What I'm actually hoping to do is extract data from chart images. For example, you might have done some googling to find, say, the transmission spectrum of a particular material, but you can't find a complete table of data. What you can find is an image of a graph. I'm planning to take the image, use appropriate image processing techinques to identify and eliminate the axes, tick marks, legend, labels, chart boundaries etc, thus leaving the actual, functional x,y values. These would then be recorded (based on user-supplied x and y min and max values), scaled to the positions of the points on the x,y curve, to convert the image of the chart line into a data table of x,y numbers.

This will probably take a few weeks, coz I'm mostly doing this at home - everybody would like it, but no project wants to pay for it (as usual). But, would anyone like to see the code when I get there? Since this is pretty much off my own bat, and not classified, there seems to be no reason why I should not post it. So, since I've got a lot of useful info from this forum, it would be gratifying to "pay off some of my debt" so to speak. If anyone would like to see the result, let me know by replying on this thread, and I'll happily post the solution when I have it.

Tony
 
have you managed to resolve this problem in VBA? i need to get an array of the pixel colours in a 12x12 bitmap image.

I want to add 30 12x12 bitmaps to an 'array of arrays' pixel by pixel. This is so i can quickly compare hundreds of other 12x12 bitmaps to them and find close matches with some sort of logic.

i have found many exapmles using getpixel and windows API but i cant get any of them to work in VBA.

i have not used HWND before but it sounds like it could do the job for me?

I would really apprechiate any help you could offer.

sorry if i am bringing an old post back to life, Alex


 
Alex,

Sorry, the answer is not yet. A new, urgent, project sprang up shortly after the previous parts of this thread, and I have not had time to address it yet.

Why hot have a bash using strongm's suggestion and post a new message w/ details of the problem if you have difficulty?

The problem is basically of two parts:

1) code to enable you to rapidly write bitmap data to and from a control via its HWND. There is loads of stuff out there on this topic, both on this forum and elsewhere. Try doing a search on DIB (Device Independent Bitmap) sections for example.

2) code to obtain the HWND of the control you want to draw to. This is where strongm's post comes in. I have not had the chance to try it, but it looks straightforward enough.

Good luck,

Tony
 
I did give what strongm said a try and it comes back and a number if you put it in a massage box like he has but i guess it is the HWND.

However i have not managed to access it as such, Most of the stuff i have read about HWND will not run in VBA.

I am thinking i might have to generate a little exe in VB that opens any .bmp files in a folder and saves a csv with the same name & .csv

It would take i while to run the code but it might just work and that is all i need.

Alex
 
If you are just doing an analysis of the data in the bitmaps, and do not actually need to display them, why bother with displaying them at all?

You know the definition of a bitmap structure.
You know where the header lies and what its values mean.
So you could just build a user-defined bitmap type (plenty of pre-written definitions exist) and assign the data from each bitmap file in turn to your UDT bitmap var (using Get), then copy the pixel data from it into your big array. Repeat until all bitmaps done.

Tony
 
I agree with the idea that i have no need to see the bitmap as i just need to compare it to another one. However i cant do it that way because i am a real noob when it comes to VB.

i could generate a definition, but i would not know where to start assigning the data or what UDP is for that matter.

I wanted to get the data pixel by pixel so it is as simple as it can be to write the comarison part.

Alex
 
Are all your bitmaps the same size and format?

If so, do you know the bytesperpixel value? This is usually 1, 3 or 4, with 4 being the easiest to work with.

If the answer to the first question is yes, and the second is 4, you can load the pixel data directly from all the bitmaps with some simple code like:

Redim pix(1 to width,1 to height) as long
Redim Comparator(1 to numberofbitmaps) as variant
For i=1 to numberofbitmaps
open bitmapname(i) for binary as #1
get#1,startpix,pix()
close #1
Comparator(i)=pix()
next i

Where Comparator() is the big array you mentioned which holds all the pixel data for all the bitmaps.

You will need to read the header of the first bitmap to find the value of the startpix variable, but thereafter you can just treat them as files containing data which starts at a fixed point.

Having got the data into your array of longs, the red, green and blue pixels are the 1st, 2nd and 3rd bytes respectively of each long and the fourth is unused (assuming 4 bytesperpixel).

To get startpix, find out the type of bitmap you're using and look up the BITMAP, BITMAPHEADER and BITMAPINFO definitions (see, for example, the the API guide available w/ VB, or just google on those terms).

UDT stands for User Defined Type. It enables you to define a data structure and treat the whole thing as a single variable. So, for example, you can define a UDT which matches the definition of a bitmap header, then read this variable direct from a bitmap file in one step. You can then interrogate the appropriate sub-section of this variable, to find where the pixel data starts in the bitmap file.

At that point, Robert is your parent's brother.

Tony
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top