Get - Set DPI for BMP,JPG & PNG files[Windows]

Share your advanced PureBasic knowledge/code with the community.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Get - Set DPI for BMP,JPG & PNG files[Windows]

Post by RASHAD »

Hi all
- Enable Admin mode

Code: Select all

UseCRC32Fingerprint() 
UsePNGImageDecoder()
UsePNGImageEncoder()
UseJPEGImageDecoder()
UseJPEGImageEncoder()

Structure _Rect
     x.f 
     y.f 
     width.f 
     height.f 
EndStructure

Global file$,resh.f, resv.f,*token, *gfx, *image, *thumb, r._Rect

CompilerIf Defined(GdiplusStartupInput, #PB_Structure) = 0
  Structure GdiplusStartupInput
    GdiPlusVersion.l
    *DebugEventCallback.Debug_Event
    SuppressBackgroundThread.l
    SuppressExternalCodecs.l
  EndStructure
CompilerEndIf

Procedure InitGDIPlus()
  OpenLibrary(0, "gdiplus.dll")
  input.GdiplusStartupInput
  input\GdiPlusVersion = 1
  CallFunction(0, "GdiplusStartup", @*token, @input, #Null)
  ProcedureReturn *token
EndProcedure

Procedure ShutDownGDIPlus(*token)
  CallFunction(0, "GdiplusShutdown", *token)
  CloseLibrary(0)
EndProcedure

Procedure.l Endianl(value.l)
  EnableASM
  MOV Eax,value
  BSWAP Eax
  DisableASM
  ProcedureReturn
EndProcedure

Procedure getdpi()
  If file$
    CallFunction(0, "GdipCreateBitmapFromFile",  @file$, @*image)
  Else
    End
  EndIf
  CallFunction(0,"GdipGetImageHorizontalResolution",*image, @resh)
  CallFunction(0,"GdipGetImageVerticalResolution",*image, @resv)  
  CallFunction(0,"GdipDisposeImage",*image)
  SetGadgetText(10, file$)
  StatusBarText(0,0,"H: "+ StrF(resh,0) +" DPI",#PB_StatusBar_Center)
  StatusBarText(0,1,"V: "+ StrF(resv,0) +" DPI",#PB_StatusBar_Center)
EndProcedure

*token = InitGDIPlus()
LoadFont(0,"Consolas",10)

OpenWindow(0,0,0,400,200,"Change DPI", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
SetGadgetFont(#PB_Default, FontID(0))
StringGadget(10,10,10,180,24,"")
TextGadget(11,10,44,85,24,"Select DPI")
SpinGadget(12,130,40,60,22,72,1200,#PB_Spin_Numeric)
SetGadgetState(12,72)
; 
ButtonGadget(1,10,120,60,20,"Open")
ButtonGadget(2,10,150,60,20,"Get DPI")
ButtonGadget(3,130,150,60,20,"Set DPI")

If CreateStatusBar(0, WindowID(0))
  AddStatusBarField(100)
  AddStatusBarField(100)
EndIf

Repeat
  Select WaitWindowEvent(10)
    Case #PB_Event_CloseWindow
      End
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1          
          InvalidateRect_(WindowID(0),0,1)
          file$ = OpenFileRequester("SELECT IMAGE","","All supported formats|*.*;*.bmp;*.jpg; *.jpeg;*.png |BMP image (*.bmp)|*.bmp*| JPEG image (*.jpg)|*.jpg |PNG image (*.png)|*.png",0)
          If file$
            Select LCase(GetExtensionPart(file$))
              Case "bmp"
                If OpenFile(0, file$)
                  If ReadWord(0) <> $4D42
                    file$ = ""
                    MessageRequester("Error","Wrong file type",#MB_OK|#MB_ICONERROR)
                    file$ = ""
                  EndIf
                  SetGadgetText(10,file$)
                  CloseFile(0)
                Else
                  MessageRequester("Error","Can not open file",#MB_OK|#MB_ICONERROR)
                EndIf
                  
              Case "jpg"
                If OpenFile(0, file$)
                  FileSeek(0,6)
                  If ReadLong(0) <> $4649464A
                    file$ = ""
                    MessageRequester("Error","Wrong file type",#MB_OK|#MB_ICONERROR)
                  EndIf
                  SetGadgetText(10,file$)
                  CloseFile(0)
                Else
                  MessageRequester("Error","Can not open file",#MB_OK|#MB_ICONERROR)                
                EndIf
              
              Case "png"
                If OpenFile(0, file$)
                  If ReadLong(0) <> $474E5089
                    file$ = ""
                    MessageRequester("Error","Wrong file type",#MB_OK|#MB_ICONERROR)
                  EndIf
                  SetGadgetText(10,file$)
                  CloseFile(0)
                Else
                  MessageRequester("Error","Can not open file",#MB_OK|#MB_ICONERROR)
                EndIf
            EndSelect
          EndIf
          CallFunction(0,"GdipCreateFromHWND",WindowID(0), @*gfx)
          CallFunction(0,"GdipCreateBitmapFromFile",@file$, @*image)
          CallFunction(0,"GdipGetImageBounds",*image, @r, @Unit)
          CallFunction(0,"GdipGetImageThumbnail",*image, Int(r\width/4), Int(r\height/4), @*thumb, 0, 0)
          CallFunction(0,"GdipDrawImageI",*gfx, *thumb, 200, 10)
          CallFunction(0,"GdipDisposeImage",*image)
          
        Case 2        
          getdpi()
          
        Case 3
          If file$         
            Select LCase(GetExtensionPart(file$))        
              Case "bmp"
                DPI = GetGadgetState(12)
                DPI = DPI*39.37
                If OpenFile(0, file$)
                  FileSeek(0, 38)
                  WriteWord(0,DPI)
                  FileSeek(0, 42)
                  WriteWord(0,DPI)
                  CloseFile(0)
                EndIf
        
              Case "jpg"
                DPI = GetGadgetState(12)
                DPI = DPI >> 8 + DPI << 8
                LoadImage(0,file$)
                SaveImage(0,file$,#PB_ImagePlugin_JPEG,9)
                OpenFile(0, file$)
                  FileSeek(0,13)
                  WriteByte(0,1)
                  FileSeek(0, 14)
                  WriteWord(0,DPI)
                  FileSeek(0, 16)
                  WriteWord(0,DPI)
                CloseFile(0)
                
              Case "png"
                DPI = GetGadgetState(12)
                DPI = Endianl(DPI*39.37)
                LoadImage(0,file$)
                *Buffer  = EncodeImage(0, #PB_ImagePlugin_PNG)        
                *pHYs = AllocateMemory(17)
                PokeL(*pHYs,$73594870)
                PokeL(*pHYs+4,DPI)
                PokeL(*pHYs+8,DPI)
                PokeB(*pHYs+12,$01)
                CRC32$ = Fingerprint(*pHYs,13,#PB_Cipher_CRC32)
                CRC32 = Val("$"+CRC32$)
                PokeL(*pHYs+13,Endianl(CRC32))        
                FreeImage(0)        
                If OpenFile(0, file$)
                    WriteData(0, *Buffer , 33)
                    WriteLong(0, $09000000)
                    WriteData(0, *pHYs, 17)
                    WriteData(0, *Buffer  + 33, MemorySize(*Buffer)-33)
                  CloseFile(0)
                EndIf        
                FreeMemory(*pHYs)
                FreeMemory(*Buffer)                                  
            EndSelect
            getdpi()
          EndIf
      EndSelect
  EndSelect
ForEver
ShutDownGDIPlus(*token)
              
Egypt my love
dige
Addict
Addict
Posts: 1247
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: Get - Set DPI for BMP,JPG & PNG files[Windows]

Post by dige »

Thx RASHAD! (y)
"Daddy, I'll run faster, then it is not so far..."
Karellen
User
User
Posts: 82
Joined: Fri Aug 16, 2013 2:52 pm
Location: Germany

Re: Get - Set DPI for BMP,JPG & PNG files[Windows]

Post by Karellen »

Great! Thanks, Rashad! :D
Stanley decided to go to the meeting room...
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Get - Set DPI for BMP,JPG & PNG files[Windows]

Post by RASHAD »

Thanks Karellen

Hi dige
I miss you man
Egypt my love
User avatar
RSBasic
Moderator
Moderator
Posts: 1218
Joined: Thu Dec 31, 2009 11:05 pm
Location: Gernsbach (Germany)
Contact:

Re: Get - Set DPI for BMP,JPG & PNG files[Windows]

Post by RSBasic »

I just saw your code now. Very good Image
Image
Image
Post Reply