alphp Posted February 21, 2012 Share Posted February 21, 2012 HelloI am creating a simple CIP3 viewer [http://www.cip4.org/documents/ppf_overview/index.html].The image comes as a raw that by adding a header becomes a PGM (P5)[http://en.wikipedia.org/wiki/Portable_graymap]. This image I have in a variable and have not found the efficient way to display it on a control.This is my code, it works ... but very slow because the PGM is large (1626x1217)expandcollapse popup#include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <String.au3> Func _ArrayEnd ($array) Return $array[UBound($array) -1] EndFunc Local $file_ppf = @ScriptDir & '\file_in.ppf' Local $file_pgm = @ScriptDir & '\file_out.pgm' ;>> For test purposes Local $handle_ppf = FileOpen($file_ppf, 16) Local $CIP3Header Do Local $line = StringStripWS(FileReadLine($handle_ppf), 3) $CIP3Header &= $line & @LF Until $line = 'CIP3PreviewImage' Local $CIP3AdmJobName = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3AdmJobName\s+\(([^\)]+)\)\s+def\s+', 1)) Local $CIP3AdmSheetName = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3AdmSheetName\s+\(([^\)]+)\)\s+def\s+', 1)) Local $CIP3AdmSheetLay = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3AdmSheetLay\s+/([^\s)]+)\s+def\s+', 1)) Local $CIP3AdmPSExtent = StringRegExp($CIP3Header, '/CIP3AdmPSExtent\s+\[([\d\.]+)\s+([\d\.]+)\]\s+def\s+', 1) Local $CIP3AdmSeparationNames = StringRegExp(_ArrayEnd(StringRegExp($CIP3Header, '/CIP3AdmSeparationNames\s+\[([^\]]+)\]\s+def\s+', 1)), '\(([^)]+)\)', 3) Local $CIP3PreviewImageWidth= _ArrayEnd(StringRegExp($CIP3Header, '/CIP3PreviewImageWidth\s+([\d\.]+)\s+def\s+', 1)) Local $CIP3PreviewImageHeight = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3PreviewImageHeight\s+([\d\.]+)\s+def\s+', 1)) Local $CIP3PreviewImageEncoding = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3PreviewImageEncoding\s+/([^\s]+)\s+def\s+', 1)) Local $CIP3PreviewImageCompression = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3PreviewImageCompression\s+/([^\s]+)\s+def\s+', 1)) Local $CIP3PreviewImageBitsPerComp = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3PreviewImageBitsPerCom(ponent)?\s+(\d+)\s+def\s+', 1)) Local $CIP3PreviewImage = FileRead($handle_ppf, $CIP3PreviewImageWidth * $CIP3PreviewImageHeight) Local $CIP3PreviewImageMatrix = StringRegExp($CIP3Header, '/CIP3PreviewImageMatrix\s+\[([-\d\.]+)\s+([-\d\.]+)\s+([-\d\.]+)\s+([-\d\.]+)\s+([-\d\.]+)\s+([-\d\.]+)\]\s+def\s+', 1) FileClose($handle_ppf) Local $PGMPreviewImage = 'P5' & @LF & $CIP3PreviewImageWidth & ' ' & $CIP3PreviewImageHeight & @LF & ((2 ^ $CIP3PreviewImageBitsPerComp) - 1) & @LF & BinaryToString($CIP3PreviewImage) Local $handle_pgm = FileOpen($file_pgm, 2) FileWrite($handle_pgm, $PGMPreviewImage) FileClose($handle_pgm) Local $CIP3View = GUICreate('CIP3View', @DesktopWidth / 3, @DesktopHeight / 3, -1, -1, $WS_MAXIMIZEBOX + $WS_SIZEBOX) Local $CIP3Preview = GUICtrlCreateGraphic (0, 0, $CIP3PreviewImageWidth, $CIP3PreviewImageHeight) GUICtrlSetBkColor($CIP3Preview, 0xf0fafa) Local $scale = 3 For $y = 1 To $CIP3PreviewImageHeight Step $scale Local $line = BinaryMid($CIP3PreviewImage, ($y - 1) * $CIP3PreviewImageWidth, $CIP3PreviewImageWidth) For $x = 1 To $CIP3PreviewImageWidth Step $scale Local $c = BinaryMid($line, $x, 1) GUICtrlSetGraphic($CIP3Preview, $GUI_GR_COLOR, $c&$c&$c) GUICtrlSetGraphic($CIP3Preview, $GUI_GR_PIXEL, $x / $scale, $y / $scale) Next Next GUISetState(@SW_SHOW, $CIP3View) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete($CIP3View)Several viewers (IrfanView for example) the display is very fastI attach a PGM file such as 129x129. map128.zipI tried the _SetImageBinaryToCtrl but do not work.Can anyone help? thanks Link to comment Share on other sites More sharing options...
Werty Posted February 21, 2012 Share Posted February 21, 2012 You could use ImageMagick (search forum), just convert it to some viewable format like png or bmp. Something like... $img = ObjCreate("ImageMagickObject.MagickImage.1") $img.Convert("input.pgm","output.png") ...then just show the output.png. Maybe GDIPlus can also handle PGM's, not certain though. Some guy's script + some other guy's script = my script! Link to comment Share on other sites More sharing options...
UEZ Posted February 21, 2012 Share Posted February 21, 2012 Where is the file_in.ppf file? Br, UEZ Please don't send me any personal message and ask for support! I will not reply! Selection of finest graphical examples at Codepen.io The own fart smells best! ✌Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!¯\_(ツ)_/¯ ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ Link to comment Share on other sites More sharing options...
alphp Posted February 21, 2012 Author Share Posted February 21, 2012 Werty: I try to solve the problem without creating temporary files. Pgm is write to disk for debugging. UEZ: Ppf files are large, in my case: 1626x1217 Bytes of the preview (1.8 Mb) and a ppf can have several (actually a preview for color separation, typically Cyan, Magenta, Yellow and Black). I have almost resolved the interpretation of the ppf and the only problem that I have not managed to solve is the display of the preview (which has pgm format), hence the word mark shows a small pgm. Thanks for your interest Link to comment Share on other sites More sharing options...
alphp Posted February 21, 2012 Author Share Posted February 21, 2012 I uploaded a ppf and documentation on CIP3: http://depositfiles.com/folders/XNVOLC77Z Link to comment Share on other sites More sharing options...
alphp Posted February 29, 2012 Author Share Posted February 29, 2012 Finally I decided to convert the PGM to PNG using pnmtopng (http://gnuwin32.sourceforge.net/packages/pngutils.htm): expandcollapse popup#include <Constants.au3> #include <WindowsConstants.au3> #include <GUIConstantsEx.au3> #include <String.au3> #include <GDIPlus.au3> #include <Memory.au3> #include <WinAPI.au3> Func _ArrayEnd ($array) Return $array[UBound($array) -1] EndFunc Local $file_ppf = @ScriptDir & '1_PruebasTinteros_tinteros_C.ppf' Local $handle_ppf = FileOpen($file_ppf, 16) Local $CIP3Header Do Local $line = StringStripWS(FileReadLine($handle_ppf), 3) $CIP3Header &= $line & @LF Until $line = 'CIP3PreviewImage' Local $CIP3AdmJobName = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3AdmJobNames+(([^)]+))s+defs+', 1)) Local $CIP3AdmSheetName = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3AdmSheetNames+(([^)]+))s+defs+', 1)) Local $CIP3AdmSheetLay = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3AdmSheetLays+/([^s)]+)s+defs+', 1)) Local $CIP3AdmPSExtent = StringRegExp($CIP3Header, '/CIP3AdmPSExtents+[([d.]+)s+([d.]+)]s+defs+', 1) Local $CIP3AdmSeparationNames = StringRegExp(_ArrayEnd(StringRegExp($CIP3Header, '/CIP3AdmSeparationNamess+[([^]]+)]s+defs+', 1)), '(([^)]+))', 3) Local $CIP3PreviewImageWidth= _ArrayEnd(StringRegExp($CIP3Header, '/CIP3PreviewImageWidths+([d.]+)s+defs+', 1)) Local $CIP3PreviewImageHeight = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3PreviewImageHeights+([d.]+)s+defs+', 1)) Local $CIP3PreviewImageEncoding = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3PreviewImageEncodings+/([^s]+)s+defs+', 1)) Local $CIP3PreviewImageCompression = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3PreviewImageCompressions+/([^s]+)s+defs+', 1)) Local $CIP3PreviewImageBitsPerComp = _ArrayEnd(StringRegExp($CIP3Header, '/CIP3PreviewImageBitsPerCom(ponent)?s+(d+)s+defs+', 1)) Local $CIP3PreviewImage = FileRead($handle_ppf, $CIP3PreviewImageWidth * $CIP3PreviewImageHeight) Local $CIP3PreviewImageMatrix = StringRegExp($CIP3Header, '/CIP3PreviewImageMatrixs+[([-d.]+)s+([-d.]+)s+([-d.]+)s+([-d.]+)s+([-d.]+)s+([-d.]+)]s+defs+', 1) FileClose($handle_ppf) Local $PGMPreviewImage = 'P5' & @LF & $CIP3PreviewImageWidth & ' ' & $CIP3PreviewImageHeight & @LF & ((2 ^ $CIP3PreviewImageBitsPerComp) - 1) & @LF & BinaryToString($CIP3PreviewImage) Local $pnmtopng = Run("pnmtopng.exe", @ScriptDir, @SW_HIDE, $STDIN_CHILD + $STDOUT_CHILD) StdinWrite($pnmtopng, Binary($PGMPreviewImage)) StdinWrite($pnmtopng) Local $PNGPreviewImage Do $PNGPreviewImage &= StdoutRead($pnmtopng) Until @error _GDIPlus_Startup() $hImage = Load_BMP_From_Mem($PNGPreviewImage) $iWidth = _GDIPlus_ImageGetWidth($hImage) $iHeight = _GDIPlus_ImageGetHeight($hImage) Local $CIP3View = GUICreate('CIP3View', @DesktopWidth / 3, @DesktopHeight / 3, -1, -1, $WS_MAXIMIZEBOX + $WS_SIZEBOX) Local $CIP3Preview = GUICtrlCreatePic('', 0, 0, $iWidth / 3, $iHeight / 3) _SetImageBinaryToCtrl($CIP3Preview, $PNGPreviewImage) GUISetState(@SW_SHOW, $CIP3View) Do Until GUIGetMsg() = $GUI_EVENT_CLOSE GUIDelete($CIP3View) ;Authors: Prog@ndy, based on code by Zedna Func _SetImageBinaryToCtrl($CtrlId, ByRef $Binary) Local $picdata = Binary($Binary) ; Fetch the Data Local $piclength = BinaryLen($picdata) ; Get Length Local $picstruct = DllStructCreate("byte[" & $piclength & "]") DllStructSetData($picstruct, 1, $picdata) Local $picmemory = DllStructGetPtr($picstruct) _SetMemoryImageToCtrl($CtrlId, $picmemory, $piclength) DllStructSetData($picstruct, 1, 0) $picstruct = "" EndFunc ;==>_SetImageBinaryToCtrl ; Authors: Zedna, based on code by Prog@ndy Func _SetMemoryImageToCtrl($CtrlId, $Pointer, $nSize) Local $hData, $pData, $pStream, $pBitmap, $hBitmap ; use GDI+ for converting to bitmap first $hData = _MemGlobalAlloc($nSize, 2) $pData = _MemGlobalLock($hData) _MemMoveMemory($Pointer, $pData, $nSize) _MemGlobalUnlock($hData) $pStream = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "int", $hData, "long", 1, "Int*", 0) $pStream = $pStream[3] _GDIPlus_Startup() $pBitmap = DllCall($ghGDIPDll, "int", "GdipCreateBitmapFromStream", "ptr", $pStream, "int*", 0) $pBitmap = $pBitmap[2] $hBitmap = _GDIPlus_BitmapCreateHBITMAPFromBitmap($pBitmap) _SetBitmapToCtrl($CtrlId, $hBitmap) If @error Then SetError(3, 0, 0) _GDIPlus_BitmapDispose($pBitmap) _GDIPlus_Shutdown() _WinAPI_DeleteObject($pStream) _MemGlobalFree($hData) EndFunc ;==>_SetMemoryImageToCtrl ; internal helper function ; Out of resources.au3 :) Func _SetBitmapToCtrl($CtrlId, $hBitmap) Local Const $STM_SETIMAGE = 0x0172 Local Const $IMAGE_BITMAP = 0 Local Const $SS_BITMAP = 0xE Local Const $GWL_STYLE = -16 Local $hWnd = GUICtrlGetHandle($CtrlId) If $hWnd = 0 Then Return SetError(1, 0, 0) ; set SS_BITMAP style to control Local $oldStyle = DllCall("user32.dll", "long", "GetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE) If @error Then Return SetError(2, 0, 0) DllCall("user32.dll", "long", "SetWindowLong", "hwnd", $hWnd, "int", $GWL_STYLE, "long", BitOR($oldStyle[0], $SS_BITMAP)) If @error Then Return SetError(3, 0, 0) Local $oldBmp = DllCall("user32.dll", "hwnd", "SendMessage", "hwnd", $hWnd, "int", $STM_SETIMAGE, "int", $IMAGE_BITMAP, "int", $hBitmap) If @error Then Return SetError(4, 0, 0) If $oldBmp[0] <> 0 Then _WinAPI_DeleteObject($oldBmp[0]) Return 1 EndFunc ;==>_SetBitmapToCtrl ;====================================================================================== ; Function Name: Load_BMP_From_Mem ; Description: Loads a image which is saved as a binary string and converts it to a bitmap or hbitmap ; ; Parameters: $mem_image: the binary string which contains any valid image which is supported by GDI+ ; Optional: $hHBITMAP: if false a bitmap will be created, if true a hbitmap will be created ; ; Remark: hbitmap format is used generally for GUI internal images ; ; Requirement(s): GDIPlus.au3, Memory.au3 ; Return Value(s): Success: handle to bitmap or hbitmap, Error: 0 ; Error codes: 1: $mem_image is not a binary string ; ; Author(s): UEZ ; Additional Code: thanks to progandy for the MemGlobalAlloc and tVARIANT lines ; Version: v0.95 Build 2011-06-11 Beta ;======================================================================================= Func Load_BMP_From_Mem($mem_image, $hHBITMAP = False) ;~ If Not IsBinary($mem_image) Then Return SetError(1, 0, 0) ;not working properly Local $declared = True If Not $ghGDIPDll Then _GDIPlus_Startup() $declared = False EndIf Local Const $memBitmap = Binary($mem_image) ;load image saved in variable (memory) and convert it to binary Local Const $len = BinaryLen($memBitmap) ;get length of image Local Const $hData = _MemGlobalAlloc($len, $GMEM_MOVEABLE) ;allocates movable memory ($GMEM_MOVEABLE = 0x0002) Local Const $pData = _MemGlobalLock($hData) ;translate the handle into a pointer Local $tMem = DllStructCreate("byte[" & $len & "]", $pData) ;create struct DllStructSetData($tMem, 1, $memBitmap) ;fill struct with image data _MemGlobalUnlock($hData) ;decrements the lock count associated with a memory object that was allocated with GMEM_MOVEABLE Local $hStream = DllCall("ole32.dll", "int", "CreateStreamOnHGlobal", "handle", $pData, "int", True, "ptr*", 0) $hStream = $hStream[3] Local $hBitmap = DllCall($ghGDIPDll, "uint", "GdipCreateBitmapFromStream", "ptr", $hStream, "int*", 0) ;Creates a Bitmap object based on an IStream COM interface $hBitmap = $hBitmap[2] Local Const $tVARIANT = DllStructCreate("word vt;word r1;word r2;word r3;ptr data; ptr") DllCall("oleaut32.dll", "long", "DispCallFunc", "ptr", $hStream, "dword", 8 + 8 * @AutoItX64, _ "dword", 4, "dword", 23, "dword", 0, "ptr", 0, "ptr", 0, "ptr", DllStructGetPtr($tVARIANT)) ;release memory from $hStream to avoid memory leak $tMem = 0 If $hHBITMAP Then Local Const $hHBmp = _GDIPlus_BitmapCreateHBITMAPFromBitmap($hBitmap) _GDIPlus_BitmapDispose($hBitmap) If Not $declared Then _GDIPlus_Shutdown() Return $hHBmp EndIf If Not $declared Then _GDIPlus_Shutdown() Return $hBitmap EndFunc ;==>Load_BMP_From_Mem Thanks for all Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now