|
-
Dec 15th, 2008, 07:28 AM
#1
Thread Starter
Frenzied Member
[RESOLVED] How to reproduce image using GetBitmapBits vs SetBitmapBits
Hello!
I'm stuck here, i see no reason why i cant properly declare a dc and/or a bitmap object for a b/g/r image data i got from getbitmapbits() api.
In my theory, this should copy the image from picturebox1 to picturebox2, by converting the picture from picbox1 to a byte array, then reproduces it in a memory bitmap, that i bitblt to the picbox2.
Code:
Private Type BITMAP
bmType As Long
bmWidth As Long
bmHeight As Long
bmWidthBytes As Long
bmPlanes As Integer
bmBitsPixel As Integer
bmBits As Long
End Type
Private Declare Function DeleteObject Lib "GDI32.dll" (ByVal hObject As Long) As Long
Private Declare Function SelectObject Lib "GDI32.dll" (ByVal hDC As Long, ByVal hObject As Long) As Long
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hDC As Long) As Long
Private Declare Function CreateCompatibleBitmap Lib "gdi32" _
(ByVal hDC As Long, ByVal nWidth As Long, ByVal nHeight As Long) As Long
Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, _
ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, _
ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
Private Sub Command1_Click()
Dim PicArray() As Byte, PicInfo As BITMAP
Dim hDC As Long, hBMP As Long, hOldBmp As Long
GetObject Picture1.Picture, Len(PicInfo), PicInfo
ReDim PicArray((PicInfo.bmWidth * PicInfo.bmHeight * (PicInfo.bmBitsPixel / 8)) - 1) As Byte
GetBitmapBits Picture1.Picture, UBound(PicArray), PicArray(0)
hDC = CreateCompatibleDC(Picture2.hDC)
hBMP = CreateCompatibleBitmap(Picture2.hDC, PicInfo.bmWidth, PicInfo.bmHeight)
hOldBmp = SelectObject(hDC, hBMP)
Debug.Print SetBitmapBits(hBMP, UBound(PicArray), PicArray(0))
Picture2.Cls
Debug.Print BitBlt(Picture2.hDC, 0, 0, PicInfo.bmWidth, PicInfo.bmHeight, hDC, 0, 0, vbSrcCopy)
SelectObject hDC, hOldBmp
DeleteObject hBMP
DeleteObject hDC
End Sub
What i am getting is looks horrible.
I checked the array to see, what is the array is containing, by using the setpixel. It seems to be the getbitmapbits runs fine, the problem should be around the dc and bitmap creations, but i have no idea why.
Code:
Dim PicArray() As Byte, PicInfo As BITMAP
Dim hDC As Long, hBMP As Long, hOldBmp As Long
Dim X As Long, Y As Long
GetObject Picture1.Picture, Len(PicInfo), PicInfo
ReDim PicArray((PicInfo.bmWidth * PicInfo.bmHeight * (PicInfo.bmBitsPixel / 8)) - 1) As Byte
GetBitmapBits Picture1.Picture, UBound(PicArray), PicArray(0)
Picture2.Cls
For X = 0 To PicInfo.bmWidth * (PicInfo.bmBitsPixel / 8) Step (PicInfo.bmBitsPixel / 8)
For Y = 0 To PicInfo.bmHeight - 2
SetPixel Picture2.hDC, X / 3, Y, RGB(PicArray(Y * ((PicInfo.bmWidth * 3) + 1) + X + 2), PicArray(Y * ((PicInfo.bmWidth * 3) + 1) + X + 1), PicArray(Y * ((PicInfo.bmWidth * 3) + 1) + X + 0))
Next
Next
-
Dec 17th, 2008, 03:47 PM
#2
Re: How to reproduce image using GetBitmapBits vs SetBitmapBits
Two small points and a big one 
When calculating the size of a buffer to hold a bitmap you must account for potential scanline padding. Each scanline must always align to a DWord, if the Width * PixelSize is not a multiple of 4 then padding bytes are added. This is not an issue with 32bpp images which always align... Ub = .bmHeight * (.bmWidth * .bmBitsPixel + 31& And -32&) \ 8 - 1
Seeing as you are using the bitmap structure you can use .bmWidthBytes instead... Ub = .bmWidthbytes * .bmHeight -1
With the calls you are using for Get/SetBitmapBits you are passing the count wrong, it should be... UBound(PicArray) + 1
The main reason why it might not work is because CreateCompatibleBitmap is most likely creating a different colour depth bitmap from the one you are trying to set to it. The kind of bitmap it creates is determined by the current desktop colour depth, on my system it creates a 32bpp bitmap. Instead of Get/SetBitmapBits you could try Get/SetDiBits, these let you specify what kind of bitmap you want.
-
Dec 17th, 2008, 11:10 PM
#3
Thread Starter
Frenzied Member
Re: How to reproduce image using GetBitmapBits vs SetBitmapBits
By using the Get/SetDiBits i got it to work. Thanks for the details, that was i missed!
vb Code:
Private Declare Function GetDIBits Lib "GDI32.dll" ( _ ByVal hDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, _ ByVal nNumScans As Long, ByRef lpBits As Any, _ ByRef lpBI As BitmapInfo, ByVal wUsage As Long) As Long Private Declare Function SetDIBits Lib "GDI32.dll" ( _ ByVal hDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, _ ByVal nNumScans As Long, ByRef lpBits As Any, _ ByRef lpBI As BitmapInfo, ByVal wUsage As Long) As Long Private Type BitmapInfoHeader ' 40 bytes biSize As Long biWidth As Long biHeight As Long biPlanes As Integer biBitCount As Integer biCompression As Long biSizeImage As Long biXPelsPerMeter As Long biYPelsPerMeter As Long biClrUsed As Long biClrImportant As Long End Type Private Type BitmapInfo bmiHeader As BitmapInfoHeader bmiColors(255) As Long End Type Private Const DIB_RGB_COLORS As Long = 0 ' Colour table in RGBs Private Sub Command2_Click() Dim DIBInf As BitmapInfo, hDC As Long, hBMP As Long ' Set the header size DIBInf.bmiHeader.biSize = Len(DIBInf.bmiHeader) hDC = Picture1.hDC hBMP = Picture1.Picture.Handle ' Fill the header structure with information about the Bitmap If (GetDIBits(hDC, hBMP, 0, 0, ByVal 0&, DIBInf, DIB_RGB_COLORS)) Then ReDim BMData(DIBInf.bmiHeader.biSizeImage - 1) As Byte Call GetDIBits(hDC, hBMP, 0, DIBInf.bmiHeader.biHeight, _ BMData(0), DIBInf, DIB_RGB_COLORS) hDC = Picture2.hDC hBMP = Picture2.Image.Handle Call SetDIBits(hDC, hBMP, 0, DIBInf.bmiHeader.biHeight, _ BMData(0), DIBInf, DIB_RGB_COLORS) End If End Sub
Last edited by Jim Davis; Dec 17th, 2008 at 11:14 PM.
-
Jan 14th, 2009, 02:48 PM
#4
New Member
Re: [RESOLVED] How to reproduce image using GetBitmapBits vs SetBitmapBits
Hi,
I'm trying to do a similar project. I am working in VB.Net 2008 express. I am trying to update a image capture / databasing program that uses VFW and make it compatible with a new USB DirectShow mircoscope. I need to be able to capture a bitmap of a live webcam. To get the image to show up in the preview window I am using Jarno Burger's webcam code found here http://www.codeproject.com/KB/audio-...ctShowNET.aspx
The only sample code for GetBitmapBIts I could find was in C so I wanted to try to play around with your code to get the screen capture of the webcam. At the moment the errors coming up say that " Picture is not a member of ' System.Windows.Forms.PictureBox' " as well as SetBitMapBits is not declared.
My ultimate goal is to be able to save the image to a folder on the hard drive where it is added to a database.
I'm still very new to VB and was hoping you might be able to post the rest of your code so I could see how it starts and try to understand what is going on.
Thanks,
Steve
-
Jan 14th, 2009, 03:08 PM
#5
Re: [RESOLVED] How to reproduce image using GetBitmapBits vs SetBitmapBits
Hi there, it's VB6 code not Vb.Net
I would also recommend not using Get/SetBitmapBits, I believe they are just there for backwards compatibility.
I think VB.Net equivalents of GetDiBits & SetDiBitsToDevice are...
System.Drawing.Bitmap.LockBits
System.Drawing.Graphics.DrawImage
Last edited by Milk; Jan 14th, 2009 at 03:15 PM.
Reason: made it a bit clearer
-
Jan 14th, 2009, 03:21 PM
#6
New Member
Re: [RESOLVED] How to reproduce image using GetBitmapBits vs SetBitmapBits
I chose to use GetBitMapBits because my only other option seems to be SampleGrabber. From what I have read SampleGrapher is more complex and MediaDet::GetBitMapBits will work just as well for what I need it to do.
Thanks for the reply, much appreciated
-
Jan 14th, 2009, 03:40 PM
#7
Re: [RESOLVED] How to reproduce image using GetBitmapBits vs SetBitmapBits
I'm pretty sure your best bet is System.Drawing.Bitmap.LockBits.
GetBitMapBits only still exists for the sake old 16 bit programs. GetDiBits is easier to use and more powerful.
-
Jul 10th, 2012, 02:55 AM
#8
Frenzied Member
Re: How to reproduce image using GetBitmapBits vs SetBitmapBits
nevermind, this comment was in error
Last edited by Ben321; Jul 11th, 2012 at 01:03 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|