Seite 1 von 1

CatchPackImage()

Verfasst: 14.05.2013 15:56
von Bisonte
Hallo...

ich probierte gerade ein wenig mit der neuen PackerLib von PB herum, und es kam eine
Prozedur heraus, die ich mal so vorstellen wollte.

Für Windows noch ein Extraschmankerl von Stefan dabei,
damit man kein ImagePlugin nutzen muss, bei jpg, png oder gar gif.

Man muss halt nur das Packerplugin initialisieren.
Ich hoffe ich hab da keine grossartigen Fehler eingebaut ;)

Als Beispiel hab ich das Theme von PB benutzt, das im Zip Format vorliegt.

Funktioniert leider nur mit einer Verzeichnisebene (Hauptverzeichnis)... aber vielleicht findet sich ja jemand der es erweitert ;)

Code: Alles auswählen

; ==============================================================================
; - Program         : CatchPackImage
; - Author          : Bisonte
; - Date            : May 14, 2013
; - Compiler        : PureBasic 5.11 (Windows - x86)
; - Target OS       : Windows, Linux, MacOS
; - Version         : 1.0
; ==============================================================================
CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
; ==============================================================================
; - Program         : CatchImageEx.pbi
; - Author          : Stefan (german forum) - modifiziert von Bisonte
; - Link            : http://www.purebasic.fr/german/viewtopic.php?p=141213#p141213
; - Date            : Feb 27, 2007
; - Compiler        : PureBasic 5.11 (Windows - x86)
; - Target OS       : Windows
; ==============================================================================
CompilerIf Not Defined(nIDXSurfaceFactory, #PB_Interface)
  Interface nIDXSurfaceFactory
    QueryInterface(a, b)
    AddRef()
    Release()
    CreateSurface(a, b, c, d, e, f, g, h)
    CreateFromDDSurface(a, b, c, d, e, f)
    LoadImage(a.p-bstr, b, c, d, e, f)
    LoadImageFromStream(a, b, c, d, e, f)
    CopySurfaceToNewFormat(a, b, c, d, e)
    CreateD3DRMTexture(a, b, c, d, e)
    BitBlt(a, b, c, d, e)
  EndInterface
CompilerEndIf
;
CompilerIf Not Defined(DXLOCKF_READ, #PB_Constant)
  #DXLOCKF_READ         = 0
CompilerEndIf
CompilerIf Not Defined(CLSCTX_INPROC_SERVER, #PB_Constant)
  #CLSCTX_INPROC_SERVER = 1
CompilerEndIf
;
Procedure CreateStreamFromMem_intern(Address, Size)
  
  Protected mem = GlobalAlloc_(#GMEM_MOVEABLE, Size)
  Protected *ptr, Stream.IStream
  
  If mem
    
    *ptr = GlobalLock_(mem)
    
    If *ptr
      CopyMemory(Address, *ptr, Size)
      CreateStreamOnHGlobal_(mem, #True, @Stream.IStream)
      GlobalUnlock_(mem)
    EndIf
    
    If Stream = 0
      GlobalFree_(mem)
    EndIf
    
  EndIf
  
  ProcedureReturn Stream
  
EndProcedure
Procedure CatchImageEX(Image, Adress, Size, Flags = 32)
  
  If Size <=0 : ProcedureReturn #False : EndIf
  
  Protected result = CoInitialize_(0)
  Protected dxtf.IDXTransformFactory, dxsf.nIDXSurfaceFactory, Stream.IStream
  Protected surf.IDXSurface, lock.IDXDCLock, DC, re.RECT, DestDC, Success
  
  If result = #S_FALSE Or result = #S_OK
    CoCreateInstance_(?CLSID_DXTransformFactory, 0, #CLSCTX_INPROC_SERVER, ?IID_IDXTransformFactory, @dxtf.IDXTransformFactory)
    If dxtf
      dxtf\QueryService(?IID_IDXSurfaceFactory, ?IID_IDXSurfaceFactory, @dxsf.nIDXSurfaceFactory)
      If dxsf
        Stream.IStream = CreateStreamFromMem_intern(Adress, Size)
        If Stream
          dxsf\LoadImageFromStream(Stream, 0, 0, 0, ?IID_IDXSurface, @surf.IDXSurface)
          If surf
            surf\LockSurfaceDC(0, #INFINITE,#DXLOCKF_READ, @lock.IDXDCLock)
            If lock
              DC = lock\GetDC()
              If DC
                GetClipBox_(DC, @re.rect)
                result = CreateImage(Image, re\right, re\bottom, Flags)
                If Image = #PB_Any : Image = result : EndIf
                If result
                  DestDC = StartDrawing(ImageOutput(Image)) 
                  If DestDC
                    Success = BitBlt_(DestDC,0,0,re\right,re\bottom,DC,0,0,#SRCCOPY)
                    StopDrawing()         
                  EndIf
                  If Success = #False : FreeImage(Image) : EndIf
                EndIf  
              EndIf
            Lock\Release()     
          EndIf
          surf\Release()
        EndIf
        dxsf\Release()
      EndIf
      Stream\Release()
      EndIf
      dxtf\Release()
    EndIf
    ;CoUninitialize_() ; dosn't work with this ?!?
  EndIf
 
  If Success : ProcedureReturn result : EndIf
  ProcedureReturn #False
  
EndProcedure
;
DataSection
  CompilerIf Not Defined(CLSID_DXTransformFactory, #PB_Label) 
    CLSID_DXTransformFactory:
    Data.l $D1FE6762
    Data.w $FC48,$11D0
    Data.b $88,$3A,$3C,$8B,$00,$C1,$00,$00
  CompilerEndIf
  CompilerIf Not Defined(IID_IDXTransformFactory, #PB_Label)  
    IID_IDXTransformFactory:
    Data.l $6A950B2B
    Data.w $A971,$11D1
    Data.b $81,$C8,$00,$00,$F8,$75,$57,$DB
  CompilerEndIf
  CompilerIf Not Defined(IID_IDXSurfaceFactory, #PB_Label) 
    IID_IDXSurfaceFactory:
    Data.l $144946F5
    Data.w $C4D4,$11D1
    Data.b $81,$D1,$00,$00,$F8,$75,$57,$DB
  CompilerEndIf
  CompilerIf Not Defined(IID_IDXSurface, #PB_Label) 
    IID_IDXSurface:
    Data.l $B39FD73F
    Data.w $E139,$11D1
    Data.b $90,$65,$00,$C0,$4F,$D9,$18,$9D
  CompilerEndIf
EndDataSection
CompilerEndIf
CompilerIf Not Defined(CatchPackImage, #PB_Procedure) ; << Catch one Imagefile from a Packfile. PackerPlugin like UseZipPacker() needed
  Procedure CatchPackImage(Image, PackFile.s, FileName.s, Plugin = #PB_Packer_Zip)
    
    Protected Result = #False, Pack, *Mem, USize, Size
    Protected fExt.s = LCase(GetExtensionPart(FileName))
    
    If FileSize(PackFile) => 0
      
      Pack = OpenPack(#PB_Any, PackFile, Plugin)
      
      If Pack
        If ExaminePack(Pack)
          While NextPackEntry(Pack)
            If PackEntryType(Pack) = #PB_Packer_File
              If PackEntryName(Pack) = FileName
                USize = PackEntrySize(Pack, #PB_Packer_UncompressedSize)
                *Mem = AllocateMemory(USize)
                If *Mem
                  Size = UncompressPackMemory(Pack, *Mem, MemorySize(*Mem))
                  If Size = USize
                    CompilerIf Defined(CatchImageEx, #PB_Procedure)
                      If FindString(fExt, "png")
                        Result = CatchImageEx(Image, *Mem, MemorySize(*Mem), 32)
                      Else
                        Result = CatchImageEx(Image, *Mem, MemorySize(*Mem), 24)
                      EndIf
                    CompilerElse
                      Result = CatchImage(Image, *Mem, USize)
                    CompilerEndIf
                  Else
                    CompilerIf #PB_Compiler_Debugger
                      Debug "Could not unpack correct!"
                    CompilerEndIf
                  EndIf
                  FreeMemory(*Mem)
                Else
                  CompilerIf #PB_Compiler_Debugger
                    Debug "Memory could not initialize!"
                  CompilerEndIf
                EndIf
                Break
              EndIf
            EndIf
          Wend        
        EndIf
        ClosePack(Pack)
      EndIf
      
      If Image = #PB_Any : Image = Result : EndIf
      If Not IsImage(Image)
        Result = #False
        CompilerIf #PB_Compiler_Debugger
          Debug "No image initialized !"  
        CompilerEndIf  
      EndIf
      
    Else
      CompilerIf #PB_Compiler_Debugger : Debug "Packfile not found !" : CompilerEndIf
    EndIf
    
    ProcedureReturn Result
    
  EndProcedure
CompilerEndIf
CompilerIf #PB_Compiler_IsMainFile ; << Example
  
  UseZipPacker()
  
  CompilerIf #PB_Compiler_OS <> #PB_OS_Windows
    UsePNGImageDecoder()
  CompilerEndIf
  
  Define.s ZipFile = #PB_Compiler_Home + "Themes\SilkTheme.zip", File = "add.png" ; << PB-Theme
  Define.i Image, Window, Button
  
  Image = CatchPackImage(#PB_Any, ZipFile, File)
  
  If IsImage(Image)
    
    Window = OpenWindow(#PB_Any, 0, 0, 80, 80, "Test", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)
    If IsWindow(Window)
      Button = ButtonImageGadget(#PB_Any, 40, 20, 40, 40, ImageID(Image))
      Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
    EndIf
  EndIf
  
CompilerEndIf