When I:
include \masm32\include\windows.inc
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
I can either invoke or call either LoadImageA or LoadImageW procedure/routine, but the problem with these both procedures/routines is that they allow me load only .bmp, .ico, .cur and .ani files.
I know but only about the Gdiplus flat api, i.e. when I:
include \masm32\include\gdiplus.inc
includelib \masm32\lib\gdiplus.lib
But I want to know about more APIs and libraries to do this task/mission, because Gdiplus is for desktop apps only, I get troubles with it and some people and MSDN not recommending it. It is also said that it is unsupported.
Hello,
There is nothing wrong with GDI+ Here are two examples, one of them is using the GDI+ functions.
Sorry that I didn't say this before, but I want to get the data of the image I load from disk, i.e. all bytes in one buffer, plus the image dimensions, i.e. width and height.
As Vortex wrote, Gdi+ is OK, and knowing Microsoft, it will be supported in the next millennium :P
Here is the source of a simple image viewer:
include \masm32\MasmBasic\Res\MbGui.asm ; part of MasmBasic (http://masm32.com/board/index.php?topic=94.0)
Event Paint
GuiImage CL$(), fit ; drag e.g. a jpg or an animated gif over the exe
GuiEndFull project attached.
Quote from: assembler on December 28, 2016, 05:50:52 AM
Sorry that I didn't say this before, but I want to get the data of the image I load from disk, i.e. all bytes in one buffer, plus the image dimensions, i.e. width and height.
Insert this under the include line in my example above:
GuiImage CL$(), info
deb 1, "Info:", GdiSI.jjWidth, GdiSI.jjHeight
Let esi=FileRead$(CL$())
deb 1, "Contents:", $esi:400
Thanks for the tips.
assembler,
GDI+ has been around for a while and is very stable, it is available in both Win32 and Win64. It is reasonably complex to use and very poorly documented but it is reliable and works well. The best easily available documentation is a CHM help file by Jose Roca and if you can get an old enough SDK from Microsoft it also has GDI+ documentation. We do have a number of people here who are experienced in GDI+ so if you have an example that you need info on, ask and someone may be able to help you.
I thank you very much, actually I am trying to use gdiplus right now, but I have a problem, that GdipCreateBitmapFromFile returns not null, but GdipCreateHBITMAPFromBitmap returns null, and I don't know what's wrong. Here is the code:
.386
.model flat, stdcall
option casemap: none
includelib \masm32\lib\masm32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\comdlg32.lib
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\gdiplus.lib
includelib \masm32\lib\msvcrt.lib
include \masm32\include\windows.inc
include \masm32\include\masm32.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
include \masm32\include\gdiplus.inc
CreateWindowExA proto :dword, :dword, :dword, :dword, :dword, :dword, :dword, :dword, :dword, :dword, :dword, :dword
GetMessageA proto :dword, :dword, :dword, :dword
TranslateMessage proto :dword
DispatchMessageA proto :dword
SetWindowLongA proto :dword, :dword, :dword
DefWindowProcA proto :dword, :dword, :dword, :dword
RtlZeroMemory proto :dword, :dword
CreateMenu proto
GetOpenFileNameW proto :dword
printf proto c :vararg
.data
string_mdiclient db "mdiclient",0
class db "classic",0
string_load_and_display_any_image db "load and display any image",0
string_load_image db "load image",0
image_path db MAX_PATH dup (0)
ofn OPENFILENAMEW <0,sizeof OPENFILENAMEW>
hBitmap dword 0
bitmap_hDC dd 0
;bitmapdata BITMAP <0,sizeof BITMAP>
image_width dd 0
image_height dd 0
dword_zero dd 0
string_error_occurred db "error occurred",0
string_eax_is_zero_after_GdipCreateBitmapFromFile db "eax is zero after GdipCreateBitmapFromFile",0
string_pBitmap_is_null db "pBitmap is null",0
string_eax_is_zero_after_GdipCreateHBITMAPFromBitmap db "eax is zero after GdipCreateHBITMAPFromBitmap",0
string_hBitmap_is_null db "hBitmap is null",0
pd_pdnl db "%d %d",10,0
.code
alert_error_occurred_and_exit:
invoke MessageBoxA, 0, offset string_error_occurred, offset string_error_occurred, MB_ICONERROR or MB_OK
invoke ExitProcess, 0
alert_eax_is_zero_after_GdipCreateBitmapFromFile_and_exit:
invoke MessageBoxA, 0, offset string_eax_is_zero_after_GdipCreateBitmapFromFile,
offset string_eax_is_zero_after_GdipCreateBitmapFromFile, MB_ICONERROR or MB_OK
invoke ExitProcess, 0
alert_pBitmap_is_null_and_exit:
invoke MessageBoxA, 0, offset string_pBitmap_is_null, offset string_pBitmap_is_null, MB_ICONERROR or MB_OK
invoke ExitProcess, 0
alert_eax_is_zero_after_GdipCreateHBITMAPFromBitmap_and_exit:
invoke MessageBoxA, 0, offset string_eax_is_zero_after_GdipCreateHBITMAPFromBitmap,
offset string_eax_is_zero_after_GdipCreateHBITMAPFromBitmap, MB_ICONERROR or MB_OK
invoke ExitProcess, 0
alert_hBitmap_is_null_and_exit:
invoke MessageBoxA, 0, offset string_hBitmap_is_null,
offset string_hBitmap_is_null, MB_ICONERROR or MB_OK
invoke ExitProcess, 0
MessageProcedure proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
local LOwParam:word
local HIwParam:word
local LOlParam:word
local HIlParam:word
local ps:PAINTSTRUCT
local pBitmap:dword
local bitmapdata:BITMAP
mov eax,wParam
mov LOwParam,ax
shr eax,16
mov HIwParam,ax
mov eax,lParam
mov LOlParam,ax
shr eax,16
mov HIlParam,ax
cmp uMsg,WM_CLOSE
je case_WM_CLOSE
cmp uMsg,WM_DESTROY
je case_WM_DESTROY
cmp uMsg,WM_COMMAND
je case_WM_COMMAND
jne invoke_DefWindowProcA
case_WM_CLOSE:
invoke DestroyWindow, hWnd
invoke ExitProcess,0
;xor eax,eax
;ret
case_WM_DESTROY:
invoke PostQuitMessage,NULL
invoke ExitProcess,0
;xor eax,eax
;ret
case_WM_COMMAND:
cmp HIwParam,0
jne invoke_DefWindowProcA
cmp LOwParam,0
jne invoke_DefWindowProcA
invoke GetOpenFileNameW, offset ofn
invoke MessageBoxW, hWnd, offset image_path, NULL, MB_ICONEXCLAMATION or MB_OK
invoke GdipCreateBitmapFromFile, offset image_path, addr pBitmap
cmp eax,0
jz alert_eax_is_zero_after_GdipCreateBitmapFromFile_and_exit
cmp pBitmap,0
jz alert_pBitmap_is_null_and_exit
invoke GdipCreateHBITMAPFromBitmap, pBitmap, offset hBitmap, 00000000h ;offset dword_zero
cmp eax,0
jz alert_eax_is_zero_after_GdipCreateHBITMAPFromBitmap_and_exit
cmp hBitmap,0
jz alert_hBitmap_is_null_and_exit
invoke SelectObject, bitmap_hDC, hBitmap
;invoke GdipCreateImageFromBitmap, pBitmap, offset pImage
invoke GdipGetImageWidth, pBitmap, offset image_width
invoke GdipGetImageHeight, pBitmap, offset image_height
;invoke GetObject, hBitmap, sizeof BITMAP, addr bitmapdata
;push bitmapdata.bmWidth
;pop image_width
;push bitmapdata.bmHeight
;pop image_height
invoke printf, offset pd_pdnl, image_width, image_height
;invoke printf, offset pd_pdnl, bitmapdata.bmWidth, bitmapdata.bmHeight
xor eax,eax
ret
case_WM_PAINT:
invoke BeginPaint, hWnd, addr ps
invoke BitBlt, eax, 0, 0, image_width, image_height, bitmap_hDC, 0, 0, SRCCOPY
invoke EndPaint, hWnd, addr ps
xor eax,eax
ret
invoke_DefWindowProcA:
invoke DefWindowProcA, hWnd, uMsg, wParam, lParam
;xor eax,eax
ret
MessageProcedure endp
;WinMainCRTStartup proc hInstance:HINSTANCE, hPrevInstance:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
mainCRTStartup proc hInstance:HINSTANCE, hPrevInstance:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
local gsi:GdiplusStartupInput
local token:dword
;local wc:WNDCLASSEX
local hWnd:HWND
local msg:MSG
local hMenu:HMENU
invoke GdiplusStartup, addr token, addr gsi, NULL
invoke CreateCompatibleDC, NULL
mov bitmap_hDC, eax
;mov wc.cbSize,sizeof WNDCLASSEX
;mov wc.style, CS_HREDRAW or CS_VREDRAW
;mov wc.lpfnWndProc, offset MessageProcedure
;mov wc.cbClsExtra,NULL
;mov wc.cbWndExtra,NULL
;push hInstance
;pop wc.hInstance
;mov wc.hbrBackground,COLOR_WINDOW+1
;mov wc.lpszMenuName,NULL
;mov wc.lpszClassName,offset class
;invoke LoadIconA,NULL,IDI_APPLICATION
;mov wc.hIcon,eax
;mov wc.hIconSm,eax
;invoke LoadCursorA,NULL,IDC_ARROW
;mov wc.hCursor,eax
;invoke RegisterClassExA,addr wc
;cmp eax,0
;jz the_end
mov ofn.lStructSize,sizeof OPENFILENAMEW
mov ofn.lpstrFile,offset image_path
mov ofn.nMaxFile,sizeof image_path
call CreateMenu
mov hMenu,eax
invoke AppendMenuA, eax, MF_STRING, 0, offset string_load_image
;invoke RtlZeroMemory, addr msg, sizeof msg
invoke CreateWindowExA, 0, offset string_mdiclient, offset string_load_and_display_any_image,
WS_OVERLAPPEDWINDOW or WS_VISIBLE, 100, 100, 640, 480, NULL, hMenu, NULL, NULL
mov hWnd, eax
invoke SetWindowLongA, eax, GWLP_WNDPROC, offset MessageProcedure
MessageLoop:
invoke IsWindow, hWnd
cmp eax,0
jz the_end
invoke IsWindowVisible, hWnd
cmp eax,0
jz the_end
invoke GetMessageA, addr msg, hWnd, 0, 0
invoke TranslateMessage, addr msg
invoke DispatchMessageA, addr msg
jmp MessageLoop
the_end:
ret
;WinMainCRTStartup endp
mainCRTStartup endp
end
Found the issue: The local variable "gsi" of type GdiplusStartupInput defined in WinMain procedure was uninitialized properly. I initialized it properly and now everything is working. I can finally see the image, that I browse from my computer, on the window.
Hi assembler,
Quotebut I want to get the data of the image I load from disk, i.e. all bytes in one buffer, plus the image dimensions, i.e. width and height.
I think this is what you want...
You can do this with the "GdipBitmapLockBits" function call,
include gdiplus.inc
includelib gdiplus.lib
.const
ImageLockModeRead equ 1
ImageLockModeWrite equ 2
ImageLockModeReadWrite equ 3
ImageLockModeUserInputBuf equ 4
PixelFormat1bppIndexed equ 30101h
PixelFormat4bppIndexed equ 30402h
PixelFormat8bppIndexed equ 30803h
PixelFormat16bppGreyScale equ 101004h
PixelFormat16bppRGB555 equ 21005h
PixelFormat16bppRGB565 equ 21006h
PixelFormat16bppARGB1555 equ 61007h
PixelFormat24bppRGB equ 21808h
PixelFormat32bppRGB equ 22009h
PixelFormat32bppARGB equ 26200Ah
PixelFormat32bppPARGB equ 0E200Bh
GdiplusStartupInput struct
GdiplusVersion dd ?
DebugEventCallback dd ?
SuppressBackgroundThread dd ?
SuppressExternalCodecs dd ?
GdiplusStartupInput ends
GdiplusSInput GdiplusStartupInput <1,NULL,FALSE,FALSE>
BitmapData struct
dwWidth dd ?
dwHeight dd ?
Stride dd ?
PixelFormat dd ?
Scan0 dd ?
Reserved dd ?
BitmapData ends
.data?
GdiplusToken dd ?
GDIplusBitmapData BitmapData <?>
FilenameW dw MAX_PATH dup (?)
.data
pImage dd NULL
PictureName db "CoolPicture.png",0
.code
; code to load image ( without error checking )
invoke GdiplusStartup,addr GdiplusToken,addr GdiplusSInput,NULL
invoke MultiByteToWideChar,CP_ACP,0,addr PictureName,-1,addr FilenameW,MAX_PATH-1
invoke GdipCreateBitmapFromFile,addr FilenameW,addr pImage
invoke GdipBitmapLockBits,pImage,NULL,ImageLockModeRead,PixelFormat32bppARGB,addr GDIplusBitmapData
mov esi,GDIplusBitmapData.Scan0 ; pointer to the bitmap data
mov eax,GDIplusBitmapData.Stride ; total length in bytes of 1 horizontal line in the bitmapdata
mov ecx,GDIplusBitmapData.dwHeight
mov edx,GDIplusBitmapData.dwWidth
; Now you have full access to the bitmap data
invoke GdipBitmapUnlockBits,pImage,addr GDIplusBitmapData
invoke GdipDisposeImage,pImage
invoke GdiplusShutdown,GdiplusToken
ret
EDIT: PixelFormat32bppRGB equ 22009h ( "h" after 22009 was missing...)
Thanks very much for the tips!
Quote from: Vortex on December 28, 2016, 05:41:05 AM
Hello,
There is nothing wrong with GDI+ Here are two examples, one of them is using the GDI+ functions.
Hi guys, I've downloaded and was studying Vortex's examples and after almost commiting a japonese Arakiri, I gave up and am asking for rescue :dazzled:
The code in question is GdipCreateBitmapFromFile, from Vortex (a couple of posts above):http://masm32.com/board/index.php?topic=5893.msg62649#msg62649 (http://masm32.com/board/index.php?topic=5893.msg62649#msg62649)
It's all cool and clear, builds ok and so forth...
But when I tried to literally copy his code within mine, nothing happens...(I tried some variations and as they didn't work, I tried a literal copy, just saying for the record).
I don't even need to post mine. The only differences are:
#1. He is using ml, and I UASM.
#2. he is on .386 and I .686p.
#3. A interesting thing: If I change this line of his from:
Quoteinvoke GdipCreateBitmapFromFile, ADDR filename, ADDR UnicodeFileName
to
Quoteinvoke GdipCreateBitmapFromFile, "logo.png", ADDR UnicodeFileName
It runs alright on his version. On mine, I get an error.
Any clear suspects (apart from obviously myself)?Humble appreciation for any possible help
Check the order of args:
GpStatus WINGDIPAPI GdipCreateBitmapFromFile(
GDIPCONST WCHAR* filename,
GpBitmap **bitmap
):
The call needs a Unicode filename, and a pointer to a DWORD variable. Typically, that looks like
push eax ; create a DWORD variable
invoke GdipCreateBitmapFromFile, wChr$("MyFile.bmp"), esp
pop edx ; voilĂ , a bitmap (if eax is zero...)
these images may also be loaded using IImgCtx (COM)
COM is a little messy, and involves a bit of a learning curve
you mentioned in your original post, "Gdiplus is for desktop apps only"
i am guessing you are referring to portable devices, and i can't really comment on which methods are supported
Quote from: dedndave on May 22, 2018, 02:12:28 AM
these images may also be loaded using IImgCtx (COM)
COM is a little messy, and involves a bit of a learning curve
you mentioned in your original post, "Gdiplus is for desktop apps only"
i am guessing you are referring to portable devices, and i can't really comment on which methods are supported
Hi Dave, the original post is not actually mine!
Quote from: jj2007 on May 22, 2018, 01:26:11 AM
Check the order of args:
GpStatus WINGDIPAPI GdipCreateBitmapFromFile(
GDIPCONST WCHAR* filename,
GpBitmap **bitmap
):
The call needs a Unicode filename, and a pointer to a DWORD variable. Typically, that looks like
push eax ; create a DWORD variable
invoke GdipCreateBitmapFromFile, wChr$("MyFile.bmp"), esp
pop edx ; voilĂ , a bitmap (if eax is zero...)
Thanks Jochen, I'll have a look. Although unless Vortex changed the calling convention in his code, this stuff should work
Hi LordAdef,
The calling convention in that example is not changed, it's STDCALL.
Guys, thanks!
I will tell the responsible for everything.... Win10... Something went stinky and neither my code or Vortex was actually working. After seeing a friend and a couple of booze, I turn it on and.... it simply work. Go figure... maybe GDI+ colapsed
Hi LordAdef,
The GdipCreateBitmapFromFile example works fine on my Windows 10 64-bit installation, version 10.0.14393
Quote from: Vortex on May 23, 2018, 05:10:37 AM
Hi LordAdef,
The GdipCreateBitmapFromFile example works fine on my Windows 10 64-bit installation, version 10.0.14393
Here too!!