|
-
Feb 13th, 2000, 08:56 PM
#1
Thread Starter
Lively Member
Hi,
I want to save a bitmap that I have created in memory to a file. I don't want to use any picture boxes (so I can't use the Save functionality of them) because this is for a usercontrol and I'm trying to keep the number of device contexts to a minimum (I'm drawing directly onto the control). I'm presuming that somewhere there's a way of saving a bitmap but am I going to have to create a file and write a bitmap header then copy the memory into the file ?
cheers
Andy
-
Feb 13th, 2000, 09:39 PM
#2
Hyperactive Member
UserControl interface is, still, a form meaning that if you draw over the control
savepicture UserControl.Picture
help you, I believe.
-
Feb 13th, 2000, 10:36 PM
#3
Thread Starter
Lively Member
Hi,
Thanks for the help. However, the usercontrol is only displaying a portion of a bitmap that I have in memory and it's the whole memory bitmap that I need to save.
cheers
Andy
-
Feb 14th, 2000, 01:17 AM
#4
Do you want to save the bitmap in full color, or as 4 or 8 bit bitmap?
Do you have the bitmap in a DC?
-
Feb 14th, 2000, 01:28 AM
#5
Thread Starter
Lively Member
Hi,
I've got the handle to the bitmap in memory. When I want to display a portion of it, I select it into a DC and stretch blit it to the usercontrol.hDC. And I need to save the bitmap as either 24bit colour (huge) or monochrome, but to be able to save as 16 or 256 colour would also be useful.
cheers
Andy
[This message has been edited by andymac (edited 02-14-2000).]
-
Feb 14th, 2000, 01:52 AM
#6
Code:
Option Explicit
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 Type BITMAPINFOHEADER
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 RGBQUAD
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
rgbReserved As Byte
End Type
Private Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
' 24 bits bitmap has no color table
'bmiColors(255) As RGBQUAD '256 colors
End Type
Private Type BITMAPFILEHEADER
bfType(1) As Byte
bfSize As Long
bfReserved1 As Integer
bfReserved2 As Integer
bfOffBits As Long
End Type
Private Const BI_RGB = 0&
Private Const GMEM_MOVEABLE = &H2
Private Const DIB_RGB_COLORS = 0
Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function GetObjectAPI Lib "gdi32" Alias "GetObjectA" (ByVal hObject As Long, ByVal nCount As Long, lpObject As Any) As Long
Private Declare Function GlobalAlloc Lib "kernel32" (ByVal wFlags As Long, ByVal dwBytes As Long) As Long
Private Declare Function GlobalLock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GetDIBits Lib "gdi32" (ByVal aHDC As Long, ByVal hBitmap As Long, ByVal nStartScan As Long, ByVal nNumScans As Long, lpBits As Any, lpBI As BITMAPINFO, ByVal wUsage As Long) As Long
Private Declare Function GlobalUnlock Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function GlobalFree Lib "kernel32" (ByVal hMem As Long) As Long
Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
Private Declare Function lwrite Lib "kernel32" Alias "_lwrite" (ByVal hFile As Long, lpBuffer As Any, ByVal wBytes As Long) As Long
Private Declare Function lclose Lib "kernel32" Alias "_lclose" (ByVal hFile As Long) As Long
Private Declare Function lcreat Lib "kernel32" Alias "_lcreat" (ByVal lpPathName As String, ByVal iAttribute As Long) As Long
Public Sub Save24bitPicture(hBitmap As Long, Dest As String)
Dim tempDC As Long
Dim bm As BITMAP
Dim bi As BITMAPINFO
Dim retVal As Long
Dim bufSize As Long
Dim ghnd As Long
Dim gptr As Long
Dim bmfh As BITMAPFILEHEADER
Dim hFile As Long
Dim Cntr As Integer
' Create a temporary memory DC, I made it compatible with the first form in the forms collection
tempDC = CreateCompatibleDC(Forms(0).hdc)
' Get the size of the picture bitmap
retVal = GetObjectAPI(hBitmap, Len(bm), bm)
' Fill the BITMAPINFO for the desired DIB
bi.bmiHeader.biSize = Len(bi.bmiHeader)
bi.bmiHeader.biWidth = bm.bmWidth
bi.bmiHeader.biHeight = bm.bmHeight
bi.bmiHeader.biPlanes = 1
' Set to 8 here to create a 8 bit DIB
' Set to 4 here to create an 4 bit DIB
bi.bmiHeader.biBitCount = 24
bi.bmiHeader.biCompression = BI_RGB
' Now calculate the data buffer size needed
bufSize = bi.bmiHeader.biWidth
' Figure out the number of bytes based on the
' number of pixels in each byte. In this case we
' really don't need all this code because this example
' always uses a 24 bits DIB, but the code is shown
' here for your future reference
Select Case bi.bmiHeader.biBitCount
Case 1
bufSize = (bufSize + 7) / 8
Case 4
bufSize = (bufSize + 1) / 2
Case 24
bufSize = bufSize * 3
End Select
' And make sure it aligns on a long boundary
bufSize = ((bufSize + 3) / 4) * 4
' And multiply by the # of scan lines
bufSize = bufSize * bi.bmiHeader.biHeight
' Now allocate a buffer to hold the data
' We use the global memory pool because this buffer
' could easily be above 64k bytes.
ghnd = GlobalAlloc(GMEM_MOVEABLE, bufSize)
gptr = GlobalLock(ghnd)
' now copy the DDB to the DIB
retVal = GetDIBits(tempDC, hBitmap, 0, bm.bmHeight, ByVal gptr, bi, DIB_RGB_COLORS)
' write the bitmapfileheader
With bmfh
.bfType(0) = &H42
.bfType(1) = &H4D ' the string "BM", I have split the integer into two bytes because the bytes got swapped
.bfSize = Len(bmfh) + Len(bi) + bufSize
.bfReserved1 = 0
.bfReserved2 = 0
.bfOffBits = Len(bi) + 14
End With
' create the file, I've chosen the api way because
' it's an easy way to copy the data block
hFile = lcreat(Dest, 0)
' write the bitmapfileheader to the file,
' for some strange reasons the structure can't be copied at once
retVal = lwrite(hFile, bmfh.bfType(0), 1)
retVal = lwrite(hFile, bmfh.bfType(1), 1)
retVal = lwrite(hFile, bmfh.bfSize, 4)
retVal = lwrite(hFile, bmfh.bfReserved1, 2)
retVal = lwrite(hFile, bmfh.bfReserved2, 2)
retVal = lwrite(hFile, bmfh.bfOffBits, 4)
' write the bitmapinfo to the file
retVal = lwrite(hFile, bi, Len(bi))
' write the data to the file
retVal = lwrite(hFile, ByVal gptr, bufSize)
' and close the file
retVal = lclose(hFile)
' Dump the global memory block
retVal = GlobalUnlock(ghnd)
retVal = GlobalFree(ghnd)
retVal = DeleteDC(tempDC)
' and were done
End Sub
[This message has been edited by Frans C (edited 02-14-2000).]
-
Feb 14th, 2000, 01:57 AM
#7
Thread Starter
Lively Member
Ta very much, I'll give it a go.
thanks
Andy
-
Feb 14th, 2000, 04:11 AM
#8
Thread Starter
Lively Member
Yep that all works. I had a few problems with the data structure being wrong, but I'm now happily saving in 4bit or 8bit colour (which is alot smaller).
Thanks very much
cheers
Andy
-
Feb 14th, 2000, 08:36 AM
#9
If your bitmap is in memory as a string (I have done that), just Open a file with the extension .bmp and
Open MyBMP for Binary as #1
Put #1,,YourString
Close #1
Let me know if you want the bitmap file structure as a word document; I learned from it.
-
Feb 14th, 2000, 06:14 PM
#10
Thread Starter
Lively Member
Hi Yaz,
The bitmap is in memory as however a bitmap is held with a pointer / handle to the memory. From the example above, you can't just write the memory in because there is no header information and the bitmap is not device independant (hence the DIB stuff in the middle). However, the method of writing a string from memory as you've shown is a good idea. Not tried it myself, but it certainly looks quick and simple.
cheers
Andy
-
Mar 2nd, 2010, 01:03 PM
#11
Re: Saving a BITMAP from memory to disk
This looks like something that I can use. However I am using VB.NET and there is no hdc property of a form anymore. Any idea on how I can make this work?
Thanks.
-
Mar 2nd, 2010, 01:21 PM
#12
Re: Saving a BITMAP from memory to disk
Are you talking about this line:
tempDC = CreateCompatibleDC(Forms(0).hdc)
If so, you don't need to create a DC for the code in post #6 above. You can simply reference one instead. So you can change
Code:
' change from: tempDC = CreateCompatibleDC(Forms(0).hdc), to
tempDC = GetDC(0&)
' then, instead of: retVal = DeleteDC(tempDC), use this
retVal = ReleaseDC(0&, tempDC)
Since you are using .Net, I'd bet you can find examples in the .Net portion of the forums.
-
Mar 2nd, 2010, 02:45 PM
#13
Re: Saving a BITMAP from memory to disk
I searched but found nothing, although I did find questions similar to mine that went unanswered. I don't think I can use this routine anyway. After making that change I get an error from GetObjectAPI "Type 'System.Drawing.Bitmap' cannot be marshaled as an unmanaged structure; no meaningful size or offset can be computed."
Thanks anyway.
-
Mar 2nd, 2010, 03:05 PM
#14
Re: Saving a BITMAP from memory to disk
Maybe you should try the .Net forum again. Searching, I found some good examples that allow you to save binary data using .Net's StreamWriter, converting image to jpg using a statement like: "PictureBox1.Image.Save(wfStream, System.Drawing.Imaging.ImageFormat.Jpeg)" (post #30 in that link)
Here are the terms I used when I searched that forum: Bitmap Stream File
-
Mar 2nd, 2010, 03:27 PM
#15
Re: Saving a BITMAP from memory to disk
Just in case you did not notice, this thread is 10 years old! Back then there was no .NET...
-
Mar 2nd, 2010, 03:48 PM
#16
Re: Saving a BITMAP from memory to disk
 Originally Posted by CVMichael
Just in case you did not notice, this thread is 10 years old! Back then there was no .NET...
I didn't even notice 
I only noticed today's post by MarMan and didn't look at the dates of the previous postings.
-
Jun 4th, 2015, 06:23 AM
#17
Addicted Member
Re: Saving a BITMAP from memory to disk
Love the idea of saving the bitmap as a string but how do I get the data from .hdc into a string?
-
Jun 4th, 2015, 07:30 AM
#18
Re: Saving a BITMAP from memory to disk
John, you are replying to a 15 year-old thread (started in 2000)
-
Jun 4th, 2015, 07:44 AM
#19
Addicted Member
Re: Saving a BITMAP from memory to disk
I know - It's still relevant!
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
|