Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Frame Callback to Array

73 views
Skip to first unread message

BeeJ

unread,
Nov 3, 2012, 7:21:11 PM11/3/12
to
Is there a way to directly go from the WebCam frame callback to a
bitmap array? i.e. without using the intermediate picbox.

Currently I can do this as a two step process.

<snip>
Step one:
In the callback I receive the pic data as pData.
StretchDIBits Picbox.hdc, 0, 0, w, h, 0, 0, w, h, ByVal
pData, m_tBI, DIB_RGB_COLORS, vbSrcCopy

' this puts the full image in a picturebox.

Step Two:
In another method

lRet = GetObject(picbox.Image.Handle, Len(m_hBmp), m_hBmp)

' Put into an array
lRet = GetBitmapBits(picbox.Image.Handle, m_hBmp.bmWidthBytes *
m_hBmp.bmHeight, m_abImgByte(0, 0, 0))

Now I can cycle through the array as needed.

' where bytColorValue = m_abImgByte(lRGBColorIx, lX, lY)

How would I go from the pData directly into the array?
Looking at the MSDN, pData contains header into that is used with the
StretchDIBits call to do the conversion in that case.


Deanna Earley

unread,
Nov 5, 2012, 4:08:38 AM11/5/12
to
On 03/11/2012 23:21, BeeJ wrote:
> Is there a way to directly go from the WebCam frame callback to a bitmap
> array? i.e. without using the intermediate picbox.
>
> Currently I can do this as a two step process.

CopyMemory().
You do need to ensure that the colour level and format is the same as
what you expect/want though.

If they aren't (or you can make it immune to these differences), create
your own DIB and DC in code (CreateDIB and CreateCompatibleDC)

Personally, I use a (very modified) DibSection class for which you can
find on www.shrinkwrapvb.com. It's used heavily in their VfW capture
samples.

--
Deanna Earley (dee.e...@icode.co.uk)
i-Catcher Development Team
http://www.icode.co.uk/icatcher/

iCode Systems

(Replies direct to my email address will be ignored. Please reply to the
group.)

BeeJ

unread,
Nov 5, 2012, 6:55:56 PM11/5/12
to
Deanna Earley formulated the question :
> On 03/11/2012 23:21, BeeJ wrote:
>> Is there a way to directly go from the WebCam frame callback to a bitmap
>> array? i.e. without using the intermediate picbox.
>>
>> Currently I can do this as a two step process.
>
> CopyMemory().
> You do need to ensure that the colour level and format is the same as what
> you expect/want though.
>
> If they aren't (or you can make it immune to these differences), create your
> own DIB and DC in code (CreateDIB and CreateCompatibleDC)
>
> Personally, I use a (very modified) DibSection class for which you can find
> on www.shrinkwrapvb.com. It's used heavily in their VfW capture samples.

Have you been to that link lately?
I can not figure out how to navigate past all the ads.
Is there some secret to it all or is that site going bye bye?


Eduardo

unread,
Nov 6, 2012, 1:27:40 AM11/6/12
to

"BeeJ" <nos...@spamnot.com> escribió en el mensaje
news:k79jmd$n7u$1...@speranza.aioe.org...

>> Personally, I use a (very modified) DibSection class for which you can
>> find on www.shrinkwrapvb.com. It's used heavily in their VfW capture
>> samples.
>
> Have you been to that link lately?
> I can not figure out how to navigate past all the ads.
> Is there some secret to it all or is that site going bye bye?

http://wayback.archive.org/web/20110201000000*/http://www.shrinkwrapvb.com/


Deanna Earley

unread,
Nov 6, 2012, 4:10:30 AM11/6/12
to
Nope, oops. There are other samples and DibSection classes around
though, or as Eduardo pointed out, the internet archive.

BeeJ

unread,
Nov 6, 2012, 4:55:40 PM11/6/12
to
Connected. Thanks!


BeeJ

unread,
Nov 6, 2012, 4:56:09 PM11/6/12
to
Got it. Will search for classes too.


BeeJ

unread,
Nov 6, 2012, 5:01:22 PM11/6/12
to
>
> CopyMemory().
> You do need to ensure that the colour level and format is the same as what
> you expect/want though.

So you are saying that the data pointed to might be just the RGB array?
No header?

Or is StretchDIBits smart enough to copy only the RGB and skip/use the
header?

>
> If they aren't (or you can make it immune to these differences), create your
> own DIB and DC in code (CreateDIB and CreateCompatibleDC)
>
> Personally, I use a (very modified) DibSection class for which you can find
> on www.shrinkwrapvb.com. It's used heavily in their VfW capture samples.

Where do I find an understandable (OK, watered down, small words, for
this old guy) discussion of this stuff?

I try to read MSDN and it makes so many assumptions about stuff that I
cannot follow it.


Deanna Earley

unread,
Nov 7, 2012, 4:17:56 AM11/7/12
to
On 06/11/2012 22:01, BeeJ wrote:
>>
>> CopyMemory().
>> You do need to ensure that the colour level and format is the same as
>> what you expect/want though.
>
> So you are saying that the data pointed to might be just the RGB array?
> No header?

Correct, that's what StretchDIBits expects.
I assumed you knew this when you looked up the functions, or did you
blindly copy and paste?

> Or is StretchDIBits smart enough to copy only the RGB and skip/use the
> header?

No, it is "A pointer to the image bits, which are stored as an array of
bytes." Nothing else.

>> If they aren't (or you can make it immune to these differences),
>> create your own DIB and DC in code (CreateDIB and CreateCompatibleDC)
>>
>> Personally, I use a (very modified) DibSection class for which you can
>> find on www.shrinkwrapvb.com. It's used heavily in their VfW capture
>> samples.
>
> Where do I find an understandable (OK, watered down, small words, for
> this old guy) discussion of this stuff?
>
> I try to read MSDN and it makes so many assumptions about stuff that I
> cannot follow it.

MSDN is the definitive source. This stuff is complicated :)
There are various sites out there that summarise it but I couldn;t give
you any examples without just looking for you.

Mike Williams

unread,
Nov 7, 2012, 12:49:40 PM11/7/12
to
"BeeJ" <nos...@spamnot.com> wrote in message
news:k748tg$3nj$1...@speranza.aioe.org...
> Is there a way to directly go from the WebCam frame callback to a bitmap
> array? i.e. without using the intermediate picbox.
> Currently I can do this as a two step process.
> Step one:
> In the callback I receive the pic data as pData. [***]
> StretchDIBits Picbox.hdc, 0, 0, w, h, 0, 0, w, h, ByVal pData,
> m_tBI, DIB_RGB_COLORS, vbSrcCopy
> ' this puts the full image in a picturebox.
> Step Two:
> In another method
> lRet = GetObject(picbox.Image.Handle, Len(m_hBmp), m_hBmp)
> ' Put into an array
> lRet = GetBitmapBits(picbox.Image.Handle, m_hBmp.bmWidthBytes *
> m_hBmp.bmHeight, m_abImgByte(0, 0, 0))
> Now I can cycle through the array as needed.
> How would I go from the pData directly into the array?

You haven't said exactly what you are getting in pData (see the line marked
[***] above). Is the data compressed, or is it straight bitmap data? If it
is not compressed (if you are currently using BI_RGB for the biCompression
member of your BITMAPINFOHEADER structure) then you should not need to do
either of the above things. All you should need to do is declare a dynamic
VB array, of either Bytes or Longs as appropriate depending on the number of
bits per pixel of your data (the value you currently have in the biBitCount
member of your BITMAPINFOHEADER structure), and also depending on how you
want to handle the data. This declaration of a dynamic VB array effectively
takes no time at all of course. Then you can use a SAFEARRAY structure to
"point" the dynamic VB array at your pData, which also effectively takes no
time at all (the actual bitmap data pointed at by pData stays exactly where
it is, with your VB array being able to examine or manipulate it directly).
You need to take account of the fact there will be some padding bytes at the
end of each scanline in pData if the pixel width of your image and the bits
per pixel it uses causes each horizontal scanline to occupy something other
than a whole multiple of four bytes, but even if this is the case (which it
is probably not) then you can easily work around it. If the pixel width of
your bitmap at pData is itself a multiple of four pixels (the pixel height
doesn't matter) then you don't need to worry about that last part I
mentioned at all, regardless of how many bits per pixel it uses. Anyway,
that's all I'm going to say on this matter. The rest is up to you.

First check out the format of DIBSections:

http://msdn.microsoft.com/en-us/library/windows/desktop/dd183567(v=vs.85).aspx

. . . and and then check out SAFEARRAY structures:

http://msdn.microsoft.com/en-gb/library/windows/desktop/ms221482(v=vs.85).aspx

. . . and then check out how you can use SAFEARRAY structures to "point"
standard VB arrays at an existing block of data in memory, various examples
of which you'll find in the archives for this group and others (but before
you do either of those things check that you are not dealing with a
compressed bitmap).

Should be good homework for you ;-)

Mike



CoderX

unread,
Nov 7, 2012, 2:18:15 PM11/7/12
to
Look at who you are asking. Cut and pasters do not learn anything. You're
giving him a fish without teaching him to fish.

"Deanna Earley" <dee.e...@icode.co.uk> wrote in message
news:k7d901$5ch$1...@speranza.aioe.org...

BeeJ

unread,
Nov 7, 2012, 2:39:41 PM11/7/12
to
>> In the callback I receive the pic data as pData. [***]
>> StretchDIBits Picbox.hdc, 0, 0, w, h, 0, 0, w, h, ByVal pData,
>> m_tBI, DIB_RGB_COLORS, vbSrcCopy
>> ' this puts the full image in a picturebox.


> You haven't said exactly what you are getting in pData (see the line marked
> [***] above).

It is a callback from the WebCam. I would have thought that the
StretchDIBits
call would help identify the data format.

It places a WebCam frame into a picturebox that is viewed and looks
exactly as expected. Axtually I take that BMP representation in PicBox
and convert it to JPEG. That too works correctly.

Is the data compressed, or is it straight bitmap data? If it is
>
> First check out the format of DIBSections:
>
> http://msdn.microsoft.com/en-us/library/windows/desktop/dd183567(v=vs.85).aspx
>
> . . . and and then check out SAFEARRAY structures:
>
> http://msdn.microsoft.com/en-gb/library/windows/desktop/ms221482(v=vs.85).aspx
>
> . . . and then check out how you can use SAFEARRAY structures to "point"
> standard VB arrays at an existing block of data in memory, various examples
> of which you'll find in the archives for this group and others (but before
> you do either of those things check that you are not dealing with a
> compressed bitmap).
>
> Should be good homework for you ;-)

More like a thesis preparation.
Thanks. I will see if this makes any sense to me.


BeeJ

unread,
Nov 7, 2012, 2:41:36 PM11/7/12
to
> In the callback I receive the pic data as pData. [***]
> StretchDIBits Picbox.hdc, 0, 0, w, h, 0, 0, w, h, ByVal pData,
> m_tBI, DIB_RGB_COLORS, vbSrcCopy
> ' this puts the full image in a picturebox.


> You haven't said exactly what you are getting in pData (see the line marked
> [***] above).

It is a callback from the WebCam. I would have thought that the
StretchDIBits
call would help identify the data format.

It places a WebCam frame into a picturebox that is viewed and looks
exactly as expected. Axtually I take that BMP representation in PicBox
and convert it to JPEG. That too works correctly.

Is the data compressed, or is it straight bitmap data? If it is
>
> First check out the format of DIBSections:
>
> http://msdn.microsoft.com/en-us/library/windows/desktop/dd183567(v=vs.85).aspx
>
> . . . and and then check out SAFEARRAY structures:
>
> http://msdn.microsoft.com/en-gb/library/windows/desktop/ms221482(v=vs.85).aspx
>
> . . . and then check out how you can use SAFEARRAY structures to "point"
> standard VB arrays at an existing block of data in memory, various examples
> of which you'll find in the archives for this group and others (but before
> you do either of those things check that you are not dealing with a
> compressed bitmap).
>
> Should be good homework for you ;-)

BeeJ

unread,
Nov 7, 2012, 2:43:04 PM11/7/12
to
> In the callback I receive the pic data as pData. [***]
> StretchDIBits Picbox.hdc, 0, 0, w, h, 0, 0, w, h, ByVal pData,
> m_tBI, DIB_RGB_COLORS, vbSrcCopy
> ' this puts the full image in a picturebox.


> You haven't said exactly what you are getting in pData (see the line marked
> [***] above).

It is a callback from the WebCam. I would have thought that the
StretchDIBits
call would help identify the data format.

It places a WebCam frame into a picturebox that is viewed and looks
exactly as expected. Axtually I take that BMP representation in PicBox
and convert it to JPEG. That too works correctly.

Is the data compressed, or is it straight bitmap data? If it is
>
> First check out the format of DIBSections:
>
> http://msdn.microsoft.com/en-us/library/windows/desktop/dd183567(v=vs.85).aspx
>
> . . . and and then check out SAFEARRAY structures:
>
> http://msdn.microsoft.com/en-gb/library/windows/desktop/ms221482(v=vs.85).aspx
>
> . . . and then check out how you can use SAFEARRAY structures to "point"
> standard VB arrays at an existing block of data in memory, various examples
> of which you'll find in the archives for this group and others (but before
> you do either of those things check that you are not dealing with a
> compressed bitmap).
>
> Should be good homework for you ;-)

BeeJ

unread,
Nov 7, 2012, 2:44:03 PM11/7/12
to
In the callback I receive the pic data as pData. [***]
StretchDIBits Picbox.hdc, 0, 0, w, h, 0, 0, w, h, ByVal
pData,
m_tBI, DIB_RGB_COLORS, vbSrcCopy
' this puts the full image in a picturebox.


'==========================================
You haven't said exactly what you are getting in pData (see the line
marked
[***] above).
'==========================================

It is a callback from the WebCam. I would have thought that the
StretchDIBits
call would help identify the data format.

It places a WebCam frame into a picturebox that is viewed and looks
exactly as expected. I take that BMP representation in PicBox and
convert it to JPEG. That too works correctly.

'==========================================
Is the data compressed, or is it straight bitmap data? If it is

First check out the format of DIBSections:

http://msdn.microsoft.com/en-us/library/windows/desktop/dd183567(v=vs.85).aspx

. . . and and then check out SAFEARRAY structures:

http://msdn.microsoft.com/en-gb/library/windows/desktop/ms221482(v=vs.85).aspx

. . . and then check out how you can use SAFEARRAY structures to
"point"
standard VB arrays at an existing block of data in memory, various
examples
of which you'll find in the archives for this group and others (but
before
you do either of those things check that you are not dealing with a
compressed bitmap).
'==========================================
Should be good homework for you ;-)

Mike Williams

unread,
Nov 7, 2012, 3:31:06 PM11/7/12
to
"BeeJ" <nos...@spamnot.com> wrote in message
news:k7eddp$9f0$1...@speranza.aioe.org...
>>
>> [Mike Williams said] You haven't said exactly what you are getting
>> on pData (see the line marked [***] above).
>
> [BeeJ said] I would have thought that the StretchDIBits
> call would help identify the data format.

I said *exactly* what you are getting! StretchDIBits is capable of dealing
with various data formats.

> It places a WebCam frame into a picturebox that is viewed and
> looks exactly as expected. Axtually I take that BMP representation
> in PicBox and convert it to JPEG. That too works correctly.

I never said it didn't! I was simply answering your question where you
complained about currently using a two step process to get the bitmap data
from pData into a VB array and where you asked, and I quote, "How would I go
from the pData directly into the array?". Did you not want me to answer that
question? If not then perhaps you shouldn't have asked it!

Your own current two step method uses a call to StretchDIBits to draw the
bitmap into a VB PictureBox followed by a call to GetBitMapBits in order to
get the bitmap data from the PictureBox into a VB array. Both of those
methods are time consuming because both of them, in their own different
ways, effectively require the shifting of the entire bitmap from one place
to another. The method I was explaining to you was a way of effectively
getting the bitmap data into a VB array without currently shifting it twice,
as you are currently doing. In fact I was explaining a way which enables you
to do it without even shifting the data once! It would be virtually
instantaneous.

>> [Mike said] First check out the format of DIBSections:
>> http://msdn.microsoft.com/en-us/library/windows/desktop/dd183567(v=vs.85).aspx
>> . . . and and then check out SAFEARRAY structures:
>> http://msdn.microsoft.com/en-gb/library/windows/desktop/ms221482(v=vs.85).aspx
>> . . . and then check out how you can use SAFEARRAY structures to
>> "point" standard VB arrays at an existing block of data in memory,
>> various
>> examples of which you'll find in the archives for this group and others
>> (but
>> before you do either of those things check that you are not dealing with
>> a compressed bitmap).
>> Should be good homework for you ;-)
>
> [BeeJ said] More like a thesis preparation.

You either want to learn this stuff or you don't. It's up to you. Copy and
Paste won't teach you much.

Mike



BeeJ

unread,
Nov 7, 2012, 4:09:57 PM11/7/12
to
Why did you ignore?

"Thanks. I will see if this makes any sense to me."

Translation from American to British. I will have to go off and study
all of this as I would if I was doing a thesis, but Cambridge material
I am not.

We can, as I have, learn a lot from sample code!
MSDN etc are very poor at enlightening you.
There is expectation of a lot of background knowledge that I just do
not have. All written by Windows C++ programmers probably. THe worst
people to write documentation. They assume too much.
I have shelves full of VB6 books and they only seem to skim the surface
on all topics. Yes, it can get very deep since most things I am trying
go past VB6 and into APIs. There is where all the fun is.

e.g. my University VB6 classes taught me little about ListView so I get
surprises on just that one control all the time.


BeeJ

unread,
Nov 7, 2012, 5:21:28 PM11/7/12
to
This method might work for some but I do need to copy the pData
(current thinking).
Thanks for the suggestion. It is a learning experience.

The app is evolving.
The callback now serves two purposes.

(1) I take a sample to process.
Processing takes considerable time and I plan to pass it to an ActiveX
EXE to do the processing. So a pData copy time is not as significant.
But doing two copies might be. But then just passing to an ActiveX EXE
is also time consuming. Got to think and try a few things.
Timer initiated.

(2) I take a sample to convert to JPEG. User initiated.

These are obviously asynchronous operations.

Questions for me.
Can I dynamically change the callback address?
This would be faster if I used your suggestion and passed the JPEG
converstion to the ActiveX EXE instead.


Mike Williams

unread,
Nov 7, 2012, 6:19:46 PM11/7/12
to

"BeeJ" wrote in message news:k7ein0$n7p$1...@speranza.aioe.org...

> Why did you ignore "Thanks. I will see if this makes any sense to me."?

Because you always seem to feel the need to include at least one negative
statement in your response to any answers you get, even when it is not
deserved, which I must admit pisses me off a bit, so I ignored your other
statements, including the one you have just quoted. Anyway, I've given you
the answer I intended to give you in response to the specific question you
had asked. The rest is up to you.

> This method might work for some but I do need to copy the pData (current
> thinking). [1]

It's up to you. From reading your question it appeared that you wanted the
data in a VB array (which I'm sure is the case or you wouldn't have asked
the question) so I assumed that you wanted that for a specific purpose
(perhaps because you wanted to examine the data pixel by pixel in a
reasonably fast way). My response was intended to give you a grounding into
how you can do that (get the data into a VB array for manipulation) and how
you can do it virtually instantaneously. Run with if if you want to, and
don't if you don't.

> This method might work for some but I do need to copy the pData (current
> thinking). [2]

Well, whatever. It's up to you. If you need to copy the data to a specific
location for some specific purpose then that's fine. I would however
strongly suggest that you copy it in a way which guarantees to retain its
full original colour depth, which your own current method of StretchDIBits
to an Autoredraw VB PictureBox (or to any other screen compatible DC) does
not, at least not on systems which are running the screen at something other
than 32 bit.

> Translation from American to British. . . . [the rest snipped]

Like I said in my original response, I've given the only reply I intend to
give in this thread. There will be no others from me, apart from this one.
It's up to you what you do with it.

Mike

Mike Williams

unread,
Nov 8, 2012, 11:21:40 AM11/8/12
to
"Mike Williams" <Mi...@WhiskyAndCoke.com> wrote in message
news:k7eqas$9h$1...@dont-email.me...
>
> Well, whatever. It's up to you. If you need to copy the data to a
> specific location for some specific purpose then that's fine. I would
> however strongly suggest that you copy it in a way which guarantees
> to retain its full original colour depth, which your own current method
> of StretchDIBits to an Autoredraw VB PictureBox (or to any other
> screen compatible DC) does not, at least not on systems which are
> running the screen at something other than 32 bit.

. . . I of course meant "your own current method of StretchDIBits to an
Autoredraw VB PictureBox (or to any other screen compatible bitmap)".

Mike



BeeJ

unread,
Nov 8, 2012, 3:48:02 PM11/8/12
to
As always I appreciate your input.


0 new messages