Page 2 of 2

Re: Get Image resolution?

Posted: Sun Oct 22, 2017 4:48 am
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

Re: Get Image resolution?

Posted: Sun Oct 22, 2017 10:50 am
by infratec
Added resolution for JPGs.

Btw. my Canon JPGs misses the APP0 segment which is mandatory :evil:

Re: Get Image resolution?

Posted: Sun Oct 22, 2017 8:44 pm
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

Re: Get Image resolution?

Posted: Sun Oct 22, 2017 10:19 pm
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

Re: Get Image resolution?

Posted: Mon Oct 23, 2017 7:36 am
by netmaestro
Lean and to the point, RASHAD. I like it very much!

Re: Get Image resolution?

Posted: Mon Oct 23, 2017 7:45 am
by RASHAD
Hi NM
Thanks
I wish you more blissful coming years
Happy birthday mate :P

Previous post updated