Table of Contents

Velikosti slik

Večina oblik zapisa slik ima glavo, v kateri so zapisani tudi podatki o širini in višini slike.

PNG

Na osnovi slike pridemo do velikosti slike takole:

> library(broman)
> f <- "../../pics/imfm.png"
> png <- file(f,"rb")
> s <- readBin(png,"raw",n=16)
> d <- hex2dec(readBin(png,"raw",n=8))
> w <- ((d[1]*256+d[2])*256+d[3])*256+d[4]
> h <- ((d[5]*256+d[6])*256+d[7])*256+d[8]
> cat("width =",w,"   height =",h,"\n")
width = 233    height = 160 
> close(png)

Pri pripravi funkcije bi bilo potrebno dodati še preverjanje, ali gre res za zapis PNG.

Za večino ostalih zapisov slik gre podobno. Pri fotografijah so podatki o fotografiji pogosto zapisani v posebni obliki EXIF.

JPEG

Pri zapisu JPEG je stvar nekoliko bolj zapletena, ker je ta sestavljen iz večih delov in je potrebno najprej najti pravi del in nato iz njega pobrati podatke o velikosti. Rešitev je že sprogramirana na spletu. Potrebno jo je bilo le prepisati v R:

> library(broman)
> # Gets the JPEG size from the array pic of data passed to the function, 
> # file reference: http://www.obrador.com/essentialjpeg/headerinfo.htm
> # https://web.archive.org/web/20131016210645/http://www.64lines.com/jpeg-width-height
> get_jpeg_size <- function(pic) {
+    # Check for valid JPEG image
+    i=1   # Keeps track of the position within the file
+    size <- length(pic)
+    if((pic[i]==0xFF)&&(pic[i+1]==0xD8)&&(pic[i+2]==0xFF)&&(pic[i+3]==0xE0)) {
+       i <- i+4
+       # Check for valid JPEG header (null terminated JFIF)
+       if((rawToChar(pic[(i+2):(i+5)])=="JFIF")&&(pic[i+6]==0x00)) {
+          # Retrieve the block length of the first block since the first block will not contain the size of file
+          x <- hex2dec(pic[i:(i+1)]); blen = x[1]*256 + x[2]
+          while(i<size) {
+             i <- i+blen               # Increase the file index to get to the next block
+             if(i >= size) return(c(0,0))  # Check to protect against segmentation faults
+             if(pic[i] != 0xFF) return(c(0,0))   # Check that we are truly at the start of another block
+             if(pic[i+1] == 0xC0) {     # 0xFFC0 is the "Start of frame" marker which contains the file size
+                # The structure of the 0xFFC0 block is quite simple 
+                # [0xFFC0][ushort length][uchar precision][ushort x][ushort y]
+                x <- hex2dec(pic[(i+5):(i+8)])
+                height <- x[1]*256 + x[2]; width <- x[3]*256 + x[4]
+                return(c(width,height))
+             }
+             else
+             {
+                i <- i+2                # Skip the block marker
+                x <- hex2dec(pic[i:(i+1)]); blen = x[1]*256 + x[2]   # Go to the next block
+             }
+          }
+          return(c(0,0))           # If this point is reached then no size was found
+       }else{ return(c(0,0)) }     # Not a valid JFIF string         
+    }else{ return(c(0,0)) }        # Not a valid SOI header
+ }
> 
> f <- "C:/Users/vlado/pics/IMG_8191.jpg" # 1280 960
> jpg <- file(f,"rb")
> pic <- readBin(jpg,"raw",n=10^8); close(jpg)
> get_jpeg_size(pic)
[1] 1280  960
vlado/work/cs/pic/dim.txt · Last modified: 2023/08/20 05:54 by vlado
 
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Noncommercial-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki