Get Image resolution?

Just starting out? Need help? Post your questions and find answers here.
collectordave
Addict
Addict
Posts: 1309
Joined: Fri Aug 28, 2015 6:10 pm
Location: Portugal

Re: Get Image resolution?

Post by collectordave »

Hi All

Thanks for the solutions.

It is all to do with the image recognition I am playing with at the moment. I have found that using openCV to select a bounding rectangle works great on images with a resolution of 300dpi or greater but a lot of images are scanned at 96 or 100 dpi which creates quite unreliable results. After finding the largest bounding rectangle I autocrop the image so that it only contains image information not borders etc which get in the way.

I need to do this to just over 600,000 images all in .jpg format. These are held in a single folder. My thoughts are to:-

1. Load image
2. Check DPI and reject if too small
3. Autocrop
4. Get and store aspect ration of image
5. Get and store Hash of image
6. Copy image to second folder

Speed is not of the essence as this will run when I am asleep and the next day while I take the wife shopping. Cross platform not so important as the code only needs to be run occassionaly when new images are added. The production of the hash database is the important thing.

PS
One thing I have noticed allready when running some of the code above is that images I grab from say a 1200 X 1200DPI image have their resolution dropped to 96 X 96 DPI. The code I am using to grab the image is here:-

Code: Select all

MyImage = LoadImage(#PB_Any,ImageFile)
GrabImage(MyImage,45,Imagex,Imagey,ImageWidth,ImageHeight)
SaveImage(45,"C:\Temp\" + GetFilePart(ImageFile,#PB_FileSystem_NoExtension)  + "_Cropped.jpg")
 FreeImage(MyImage) 
Imagex,Imagey etc are obtained from OpenCV for the largest bounding rectangle. The idea being to grab the portion of the image inside this bounding rectangle to use for the hash. I have not investigated further as yet but would like to maintain the original image DPI.

Thanks to all

CD
Any intelligent fool can make things bigger and more complex. It takes a touch of genius — and a lot of courage to move in the opposite direction.
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Get Image resolution?

Post by infratec »

Added resolution for JPGs.

Btw. my Canon JPGs misses the APP0 segment which is mandatory :evil:
infratec
Always Here
Always Here
Posts: 6817
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Get Image resolution?

Post by infratec »

A fast an jpg only version for DPI:

Code: Select all

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf


Structure GetImageInfoStructure
  xdensity.i
  ydensity.i
EndStructure



Procedure.i GetJPGDPI(Filename$, *ImageInfo.GetImageInfoStructure)
  
  Protected Result.i, File.i, ReadSize, *Buffer, Marker.u, Ptr.i
  
  
  File = ReadFile(#PB_Any, Filename$)
  If File
    *Buffer = AllocateMemory(64,  #PB_Memory_NoClear)
    If *Buffer
      If Lof(File) < MemorySize(*Buffer)
        ReadSize = Lof(File)
      Else
        ReadSize = MemorySize(*Buffer)
      EndIf
      If ReadData(File, *Buffer, ReadSize) = ReadSize
        If PeekU(*Buffer) = $D8FF
          Ptr = 2

            Marker = PeekU(*Buffer + Ptr)
            ;Debug Hex(Marker)
            
            If Marker = $E0FF ; should be the first marker after FFD8
              Select PeekA(*Buffer + Ptr + 11)
                Case 1 ; dpi
                  *ImageInfo\xdensity = ((PeekA(*Buffer + Ptr + 12) << 8) | PeekA(*Buffer + Ptr + 13))
                  *ImageInfo\ydensity = ((PeekA(*Buffer + Ptr + 14) << 8) | PeekA(*Buffer + Ptr + 15))
                Case 2 ; dcm
                  *ImageInfo\xdensity = ((PeekA(*Buffer + Ptr + 12) << 8) | PeekA(*Buffer + Ptr + 13)) * 2.54
                  *ImageInfo\ydensity = ((PeekA(*Buffer + Ptr + 14) << 8) | PeekA(*Buffer + Ptr + 15)) * 2.54
                Default ; scaling ?
                  *ImageInfo\xdensity = 0
                  *ImageInfo\ydensity = 0
              EndSelect
              Result = #True
            EndIf
            
        EndIf
      EndIf
      
      FreeMemory(*Buffer)
    EndIf
    CloseFile(File)
  EndIf
  
  ProcedureReturn Result
  
EndProcedure




CompilerIf #PB_Compiler_IsMainFile
  
  Define Filename$, Info$, ImageInfo.GetImageInfoStructure
  Define Dir$, Dir.i
  
  Dir$ = PathRequester("Choose a directory", "")
  If Dir$ <> ""
    Dir = ExamineDirectory(#PB_Any, Dir$, "*.jpg")
    If Dir
      While NextDirectoryEntry(Dir)
        If DirectoryEntryType(Dir) = #PB_DirectoryEntry_File
          Filename$ = DirectoryEntryName(Dir)
          ImageInfo\xdensity = 0
          ImageInfo\ydensity = 0
          If GetJPGDPI(Dir$ + Filename$, @ImageInfo)
            Info$ = Filename$ + " -> " + Str(ImageInfo\xdensity) + "x" + Str(ImageInfo\ydensity)
            Debug Info$
          EndIf
        EndIf
      Wend
      FinishDirectory(Dir)
    EndIf
  EndIf
  
CompilerEndIf
The APP0 marker with the densitiy inside has to be the first behind the SOI marker.
Else the file is not JPG conform :wink:

Bernd
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Get Image resolution?

Post by RASHAD »

Get any image Width ,Height and Resolution without loading using VBS

Code: Select all

Repeat
  file$ = OpenFileRequester("Please choose file to load", "",  "Image (*.bmp;*.gif;*.jpeg;*.jpg;*.png;*.tif;*.tiff)" , 0)
  If file$
    DeleteFile(GetHomeDirectory()+"resolution.vbs")
    OpenFile(0,GetHomeDirectory()+"resolution.vbs")
      WriteStringN(0,"Set objImage = CreateObject("+Chr(34)+"WIA.ImageFile"+Chr(34)+")")
      WriteStringN(0,"objImage.LoadFile "+Chr(34)+file$+Chr(34))
      WriteStringN(0,"Wscript.Echo "+Chr(34)+"Width: "+Chr(34)+" & "+"objImage.Width"+" & "+Chr(34) +" pixels" +Chr(34))
      WriteStringN(0,"Wscript.Echo "+Chr(34)+"Height: "+Chr(34)+" & "+"objImage.Height"+" & "+Chr(34) +" pixels" +Chr(34))
      WriteStringN(0,"Wscript.Echo "+Chr(34)+"Resolution: "+Chr(34)+" & "+"Round(objImage.HorizontalResolution)"+" & "+Chr(34)+"  DPI"+Chr(34))
      WriteStringN(0,"Wscript.Echo "+Chr(34)+"Pixel Depth: "+Chr(34)+" & "+"objImage.PixelDepth"+" & "+Chr(34)+"  BPP"+Chr(34))
      WriteStringN(0,"Wscript.Echo "+Chr(34)+"Frame Count : "+Chr(34)+" & "+"objImage.FrameCount"+" & "+Chr(34)+"  Frame/s"+Chr(34))
      WriteStringN(0,"Wscript.Echo "+Chr(34)+"File Extension : "+Chr(34)+" & "+"objImage.FileExtension"+" & "+Chr(34)+"  Format"+Chr(34))
      WriteStringN(0,"If "+"objImage.FileExtension" + " = "+Chr(34) +"png"+Chr(34)+" Then")
        WriteStringN(0,"Wscript.Echo "+Chr(34)+"IsAlphaPixelFormat : "+Chr(34)+" & "+"objImage.IsAlphaPixelFormat")
      WriteStringN(0,"End If")
    CloseFile(0)
    RunProgram("WScript.exe",GetHomeDirectory()+"resolution.vbs","",#PB_Program_Wait) 
  Else
    End
  EndIf
  Result = MessageRequester("","Need more ?",#PB_MessageRequester_YesNo|#MB_ICONQUESTION)
  If Result = #PB_MessageRequester_No
    End
  EndIf
Until GetAsyncKeyState_(#VK_ESCAPE) & 32768 = 32768
Edit :Modified
Edit #2
Last edited by RASHAD on Mon Oct 23, 2017 9:22 am, edited 3 times in total.
Egypt my love
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8425
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: Get Image resolution?

Post by netmaestro »

Lean and to the point, RASHAD. I like it very much!
BERESHEIT
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: Get Image resolution?

Post by RASHAD »

Hi NM
Thanks
I wish you more blissful coming years
Happy birthday mate :P

Previous post updated
Egypt my love
Post Reply