Jump to content



Photo

View PGM file


  • Please log in to reply
5 replies to this topic

#1 alphp

alphp

    Seeker

  • Normal Members
  • 4 posts

Posted 21 February 2012 - 10:20 AM

Hello

I 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)

Plain Text         
#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 fast
I attach a PGM file such as 129x129. Attached File  map128.zip   13.82K   27 downloads

I tried the _SetImageBinaryToCtrl but do not work.

Can anyone help? thanks





#2 Werty

Werty

    Polymath

  • Active Members
  • PipPipPipPip
  • 225 posts

Posted 21 February 2012 - 10:42 AM

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.

#3 UEZ

UEZ

    Never say never

  • MVPs
  • 3,600 posts

Posted 21 February 2012 - 10:42 AM

Where is the file_in.ppf file?

Br,
UEZ

 
The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯


#4 alphp

alphp

    Seeker

  • Normal Members
  • 4 posts

Posted 21 February 2012 - 03:01 PM

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

#5 alphp

alphp

    Seeker

  • Normal Members
  • 4 posts

Posted 21 February 2012 - 04:55 PM

I uploaded a ppf and documentation on CIP3: http://depositfiles.com/folders/XNVOLC77Z

#6 alphp

alphp

    Seeker

  • Normal Members
  • 4 posts

Posted 29 February 2012 - 10:08 AM

Finally I decided to convert the PGM to PNG using pnmtopng (http://gnuwin32.sourceforge.net/packages/pngutils.htm):

Plain Text         
#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




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users