Win32 C/C++ Load Image from memory buffer
Nevermind, I found my solution! Here's the initializing code:
std::ifstream is;
is.open("Image.bmp", std::ios::binary);
is.seekg (0, std::ios::end);
length = is.tellg();
is.seekg (0, std::ios::beg);
pBuffer = new char [length];
is.read (pBuffer,length);
is.close();
tagBITMAPFILEHEADER bfh = *(tagBITMAPFILEHEADER*)pBuffer;
tagBITMAPINFOHEADER bih = *(tagBITMAPINFOHEADER*)(pBuffer+sizeof(tagBITMAPFILEHEADER));
RGBQUAD rgb = *(RGBQUAD*)(pBuffer+sizeof(tagBITMAPFILEHEADER)+sizeof(tagBITMAPINFOHEADER));
BITMAPINFO bi;
bi.bmiColors[0] = rgb;
bi.bmiHeader = bih;
char* pPixels = (pBuffer+bfh.bfOffBits);
char* ppvBits;
hBitmap = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**) &ppvBits, NULL, 0);
SetDIBits(NULL, hBitmap, 0, bih.biHeight, pPixels, &bi, DIB_RGB_COLORS);
GetObject(hBitmap, sizeof(BITMAP), &cBitmap);
Displaying all Bitmap Types from a Memory Buffer with MFC or Win32
Hans is correct to say that bi.bmiColors
was not being treated correctly. Instead of handling the bi.bmiColors
table directly, just point pBitmapInfo
to the appropriate offset in BITMAPFILEHEADER
and cast. This takes care of the color table automatically. And yes, pBitmapInfo
and pBitmapInfoHeader
do point to the same place; what they point to is casted differently in each case. Both of those pointers a required by the CreateDIBitmap()
function.
pBitmapFileHeader = (LPBITMAPFILEHEADER)buf1;
pBitmapInfoHeader = (LPBITMAPINFOHEADER)(buf1+sizeof(BITMAPFILEHEADER));
pBitmapInfo = (LPBITMAPINFO)(buf1+sizeof(BITMAPFILEHEADER));
pPixels = (buf1+pBitmapFileHeader->bfOffBits);
Then in OnPaint() do:
g_hBmp = CreateDIBitmap(dcPaint, pBitmapInfoHeader, CBM_INIT, (VOID *) pPixels, pBitmapInfo, DIB_RGB_COLORS);
Write to a memory buffer and check if it is full with a SEH exception on Win32 platform?
Yes. Use VirtualAlloc
. With VirutalProtect
used in conjunction, you can even make this guard zone only memory page sized (4096 bytes, not whole 64KB).
Note that for stack it is handled by OS, you can only control this by SetThreadStackGuarantee
to set the amount of buffer before stack overflow, and _resetstkoflw
to fix (restore) guard after stack overflow exception is hadnled.
How can I retrieve an image data buffer from clipboard memory (uintptr)?
@JimB is correct: user32!GetClipboardData()
returns a HGLOBAL
, and a comment example over there suggests using kernel32!GlobalLock()
to a) globally lock that handle, and b) yield a proper pointer to the memory referred to by it.
You will need to kernel32!GlobalUnlock()
the handle after you're done with it.
As to converting pointers obtained from Win32 API functions to something readable by Go, the usual trick is casting the pointer to an insanely large slice. To cite the "Turning C arrays into Go slices" of "the Go wiki article on cgo
":
To create a Go slice backed by a C array (without copying the original
data), one needs to acquire this length at runtime and use a type
conversion to a pointer to a very big array and then slice it to the
length that you want (also remember to set the cap if you're using Go 1.2 > or later), for example (see http://play.golang.org/p/XuC0xqtAIC for a
runnable example):import "C"
import "unsafe"
...
var theCArray *C.YourType = C.getTheArray()
length := C.getTheArrayLength()
slice := (*[1 << 30]C.YourType)(unsafe.Pointer(theCArray))[:length:length]
It is important to keep in mind that the Go garbage collector will not
interact with this data, and that if it is freed from the C side of
things, the behavior of any Go code using the slice is nondeterministic.
In your case it will be simpler:
h := GlobalLock()
defer GlobalUnlock(h)
length := somehowGetLengthOfImageInTheClipboard()
slice := (*[1 << 30]byte)(unsafe.Pointer((uintptr(h)))[:length:length]
Then you need to actually read the bitmap.
This depends on the format of the Device-Independent Bitmap (DIB) available for export from the clipboard.
See this and this for a start.
As usually, definitions of BITMAPINFOHEADER
etc are easily available online in the MSDN site.
Unable to load .bmp files win32
It seems that you never allocate a buffer for the filename.
The different data types can be found in this SO answer.
Your szFileName
is defined as an
LPTSTR = char* or wchar_t* depending on _UNICODE
so it's a pointer, but in your code sample you didn't reserve memory for this pointer.
ofn.lpstrFile = (LPWSTR)szFileName; // in WndProc
LoadAndBlitBitmap(LPCWSTR szFileName...) // passed as CONST
LoadImage(NULL, szFileName...) // passed as parameter
OpenFileDialog(hWnd, szFileName, ...) // passed as parameter
if (szFileName) ... // check if !NULL
LoadAndBlitBitmap(szFileName, hdc); // passed as parameter
But you never allocate the necessary memory to the pointer...
In the OPENFILENAME
structure lpstrFile
is defined as:
The file name used to initialize the File Name edit control.
The first character of this buffer must be NULL if initialization is not necessary.
When the GetOpenFileName or GetSaveFileName function returns successfully, this buffer contains the drive designator, path, file name, and extension of the selected file...If the buffer is too small, the function returns FALSE and the CommDlgExtendedError function returns FNERR_BUFFERTOOSMALL. In this case, the first two bytes of the lpstrFile buffer contain the required size, in bytes or characters.
So you simply need to assign a buffer to szFileName
to fix that problem.
That will solve your
In the case ID_FILE_LOADIMAGES, the "szFileName" is testing false even after the user has chosen a certain bmp image and clicked ok.
problem. It returns FALSE
because your "buffer" (=none) is too small.
Related Topics
Fast Multiplication/Division by 2 for Floats and Doubles (C/C++)
Wrap Overloaded Function via Std::Function
The Cxx Compiler Identification Is Unknown
Preventing Gcc from Automatically Using Avx and Fma Instructions When Compiled with -Mavx and -Mfma
Fastest Timing Resolution System
Convert Bitmap to Png In-Memory in C++ (Win32)
Are Non Dereferenced Iterators Past the "One Past-The-End" Iterator of an Array Undefined Behavior
Why Array Index Start from '0'
How Many Decimal Places Does the Primitive Float and Double Support
Forward Declaration & Circular Dependency
Opencv's Canny Edge Detection in C++
Multiple "Could Not Be Resolved" Problems Using Eclipse with Mingw
Advantages of Using Initializer List
How to Decide If a Template Specialization Exist
How to Convert a String Literal to Unsigned Char Array in Visual C++