====== Velikosti slik ====== Večina oblik zapisa slik ima glavo, v kateri so zapisani tudi podatki o širini in višini slike. ===== PNG ===== Na osnovi [[https://stackoverflow.com/questions/54845745/not-able-to-read-ihdr-chunk-of-a-png-file|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 [[https://en.wikipedia.org/wiki/Exif|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 [[https://web.archive.org/web/20131016210645/http://www.64lines.com/jpeg-width-height|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) 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