How to convert a binary console output to a (h) bitmap?

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
Frosti
Posts: 426
Joined: 27 Oct 2017, 14:30
Contact:

How to convert a binary console output to a (h) bitmap?

12 Dec 2018, 15:54

I've been using pdftopng a long time to preview one page of a pdf.
Now I discovered an option to send this png to stdout.

This is from manual page:
Pdftopng reads the PDF file, PDF-file, and writes one PNG file for each page, PNG-root-nnnnnn.png, where nnnnnn is the page number.
If PNG-root is ´-’, the image is sent to stdout (this is probably only useful when converting a single page)

Okay, this works fine. But the header of the extracted png image looks, however, different than e.g. one that was saved with MS-Paint. When I looked at the end of a png file,
I also saw a difference here. I have tried to save stdout for test purposes in different CodePage formats (CP0, CP850, UTF-8), except that the displayed characters are similar
to CP0 compared to a displayable png file, unfortunately, you can not create a correct PNG format.

89504E470D0A1A0A 0E04FA5757C763A5 89A6E6956B57D7D6 D6EADCC1A953A706 ...... | ‰PNG......úWWÇc¥‰¦æ•kW×ÖÖêÜÁ©S§. ì@}}ýÔ.¦ºJŽ9fLUEEÛ•-³fÍ:ª¡áÔ™§.’| StdOut (CP0)
89504E470D0A1A0A D00E04FA5757C763 A589A6E6956B57D7 D6D6EADCC1A953A7 ...... | ‰PNG....Ð..úWWÇc¥‰¦æ•kW×ÖÖêÜÁ©S§.ì@}}ýÔ.¦ºJŽ9fLUEEÛ•-³fÍ:ª¡áÔ™§. | StdOut (CP850)
89504E470D0A1A0A 0000000D49484452 000002520000033E 08020000005EFC78 ...... | ‰PNG........IHDR...R...>.....^üx.................................| png was saved directly to disc from pdftopng
The first 8byte block's are similar. The file size is too small. 8kb maximum over stdout2var to 234kb by direct output as an image file.

And here's my code borrowed from following thread: Download binary image into var, convert to bitmap & show in GUI

Code: Select all

#Persistent
PdfPath:= A_ScriptDir "\test.pdf"
dpi:= 72
page:= 1
q := Chr(0x22)
XpdfPath := A_ScriptDir "\xdf\pdftopng.exe" 			;. q

CmdString := XpdfPath . " -f " page " -l " page " -r " . dpi . " -freetype yes -aaVector yes " . q . PdfPath . q . " " . q . "-" . q   ;<<--- use "-" to redirect the output of the image to the console 
StdOut:= StdOutToVar(CmdString)
If Instr(StdOut, "Error") 
{
	MsgBox, % StdOut
        ExitApp
} 
 else 
{
	size:= VarSetCapacity(StdOut)
	ImageBin:= StdOut
	BinImgToBITMAP(size, hBitmap, ImageBin)
}

imgH :=  Bitmap_GetHeight(HBITMAP)  ; GET IMAGE HEIGHT
imgW := Bitmap_GetWidth(HBITMAP)	  ; GET IMAGE WIDTH
Gui, Margin, 0, 0
Gui, Add, Picture, % "x0 y0 w" imgW " h" imgH " hwndHPic1", hBitmap: %HBITMAP%
Gui, Show, , Image				
return

BinImgToBITMAP(size, byref hBitmap, byref Imagebin) {
	if hBitmap
		DllCall("DeleteObject", "ptr", hBitmap)
	hData := DllCall("Kernel32.dll\GlobalAlloc", "UInt", 2, "UPtr", size, "UPtr")
	pData := DllCall("Kernel32.dll\GlobalLock", "Ptr", hData, "UPtr")
	DllCall("Kernel32.dll\RtlMoveMemory", "Ptr", pData, "Ptr", &ImageBin, "UPtr", size)
	DllCall("Kernel32.dll\GlobalUnlock", "Ptr", hData)
	DllCall("Ole32.dll\CreateStreamOnHGlobal", "Ptr", hData, "Int", True, "PtrP", pStream)
	hGdip := DllCall("Kernel32.dll\LoadLibrary", "Str", "Gdiplus.dll", "UPtr")
	VarSetCapacity(SI, 16, 0), NumPut(1, SI, 0, "UChar")
	DllCall("Gdiplus.dll\GdiplusStartup", "PtrP", pToken, "Ptr", &SI, "Ptr", 0)
	DllCall("Gdiplus.dll\GdipCreateBitmapFromStream",  "Ptr", pStream, "PtrP", pBitmap)
	DllCall("Gdiplus.dll\GdipCreateHBITMAPFromBitmap", "Ptr", pBitmap, "PtrP", hBitmap, "UInt", 0)
	DllCall("Gdiplus.dll\GdipDisposeImage", "Ptr", pBitmap)
	DllCall("Gdiplus.dll\GdiplusShutdown", "Ptr", pToken)
	DllCall("Kernel32.dll\FreeLibrary", "Ptr", hGdip)
	DllCall(NumGet(NumGet(pStream + 0, 0, "UPtr") + (A_PtrSize * 2), 0, "UPtr"), "Ptr", pStream)
}

StdOutToVar(cmd) {						                                                            							

	;https://github.com/cocobelgica/AutoHotkey-Util/blob/master/StdOutToVar.ahk
	DllCall("CreatePipe", "PtrP", hReadPipe, "PtrP", hWritePipe, "Ptr", 0, "UInt", 0)
	DllCall("SetHandleInformation", "Ptr", hWritePipe, "UInt", 1, "UInt", 1)

	VarSetCapacity(PROCESS_INFORMATION, (A_PtrSize == 4 ? 16 : 24), 0)    ; http://goo.gl/dymEhJ
	cbSize := VarSetCapacity(STARTUPINFO, (A_PtrSize == 4 ? 68 : 104), 0) ; http://goo.gl/QiHqq9
	NumPut(cbSize, STARTUPINFO, 0, "UInt")                                ; cbSize
	NumPut(0x100, STARTUPINFO, (A_PtrSize == 4 ? 44 : 60), "UInt")        ; dwFlags
	NumPut(hWritePipe, STARTUPINFO, (A_PtrSize == 4 ? 60 : 88), "Ptr")    ; hStdOutput
	NumPut(hWritePipe, STARTUPINFO, (A_PtrSize == 4 ? 64 : 96), "Ptr")    ; hStdError

	if !DllCall(
	(Join Q C
		"CreateProcess",            					; http://goo.gl/9y0gw
		"Ptr",  0,                   							; lpApplicationName
		"Ptr",  &cmd,                						; lpCommandLine
		"Ptr",  0,                   							; lpProcessAttributes
		"Ptr",  0,                   							; lpThreadAttributes
		"UInt", true,                						; bInheritHandles
		"UInt", 0x08000000,     						; dwCreationFlags
		"Ptr",  0,                   							; lpEnvironment
		"Ptr",  0,                   							; lpCurrentDirectory
		"Ptr",  &STARTUPINFO,        				; lpStartupInfo
		"Ptr",  &PROCESS_INFORMATION 		; lpProcessInformation
	)) {
		DllCall("CloseHandle", "Ptr", hWritePipe)
		DllCall("CloseHandle", "Ptr", hReadPipe)
		return ""
	}

	DllCall("CloseHandle", "Ptr", hWritePipe)
	VarSetCapacity(buffer, 4096, 0)
	while DllCall("ReadFile", "Ptr", hReadPipe, "Ptr", &buffer, "UInt", 4096, "UIntP", dwRead, "Ptr", 0)
		sOutput .= StrGet(&buffer, dwRead, "CP0")

	DllCall("CloseHandle", "Ptr", NumGet(PROCESS_INFORMATION, 0))         ; hProcess
	DllCall("CloseHandle", "Ptr", NumGet(PROCESS_INFORMATION, A_PtrSize)) ; hThread
	DllCall("CloseHandle", "Ptr", hReadPipe)
	return sOutput
}

Bitmap_GetWidth(hBitmap) {                                                                                                        	;-- Returns the width of a bitmap
   Static Size := (4 * 5) + A_PtrSize + (A_PtrSize - 4)
   VarSetCapacity(BITMAP, Size, 0)
   DllCall("Gdi32.dll\GetObject", "Ptr", hBitmap, "Int", Size, "Ptr", &BITMAP, "Int")
   Return NumGet(BITMAP, 4, "Int")
}

Bitmap_GetHeight(hBitmap) {                                                                                                       	;-- Returns the height of a bitmap
   Static Size := (4 * 5) + A_PtrSize + (A_PtrSize - 4)
   VarSetCapacity(BITMAP, Size, 0)
   DllCall("Gdi32.dll\GetObject", "Ptr", hBitmap, "Int", Size, "Ptr", &BITMAP, "Int")
   Return NumGet(BITMAP, 8, "Int")
}

I know exactly where the problem lies! It's up to me!
Image

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: ccqcl, Descolada, mikeyww and 373 guests