Dpi van png in javascript

Wat is dpi

De grote van een digitale afbeelding verschilt van een geprinte afbeelding. Dit wordt aangegeven met de dpi van de afbeelding. Dpi staat voor dots per inch, ook wel uitgedrukt in ppi (pixels per inch) of ppc (pixels per centimeter). Met behulp van deze verhouding kan uitgerekend worden wat de geprinte grote van een afbeelding zal worden.

Bij het vertonen van afbeeldingen op een website is de dpi normaal gesproken niet belangrijk. Echter wanneer de afbeelding vervolgens uitgeprint wordt is deze waarde ineens wel van belang. Ook bij het printvoorbeeld zal hier rekening mee moeten worden gehouden.

De dpi staat in het afbeelding bestand beschreven en heeft anders een standaard waarde van 72. Meestal wordt deze waarde opgehaald met behulp van een code bibliotheken. Deze was echter nog niet aanwezig voor javascript waardoor de waarde er handmatig uitgehaald moest worden.

Een andere kijk op een afbeelding

In een afbeelding bestand zoals png staat vaak meer informatie dan alleen de afbeelding zelf. Zo is hierin het bestandstype, de grote, de kleuren waardes, de transparentie en nog vele andere gegevens terug te vinden. De details hiervan zijn terug te vinden op de Libpng specificaties website

De gegevens die hier echter belangrijk zijn zijn de pHYs wat komt van Physical pixel dimensions. De 8 bytes die hierna komen beschrijven de afmetingen van de afbeelding voor de horizontale en verticale as. Hierna komt nog een byte die de eenheid van de opgegeven afmetingen aangeeft. Over het algemeen komen hier maar twee verschillende waardes voor: 0 (eenheid onbekend) en 1 (afmeting in meters). Let op, omdat de afmeting in meters is, is dit dus niet de dpi maar de ppm van de afbeelding. Deze moet eerst nog omgerekend worden.

logo.png file.png
Figuur 1 - Voorbeeld png afbeelding
Figuur 2 - Een klein deel van figuur 1 als hexidecimals in hexed. (let ook op de pHYs waarde in de rechter kolom)

Code

Om deze gegevens in javascript uit te lezen wordt de afbeelding eerst omgezet naar een 8 bit array. Vervolgens wordt door alle waarden geloopt opzoek naar de achtereenvolgende waarden p H Y s. Als deze gevonden zijn worden de volgende 8 waarden uitgelezen en omgezet naar 2 decimale waarden. Hierna wordt gecontroleerd of de waarden in meters zijn opgegeven, en worden deze vervolgens omgezet naar inches om zo de dpi te verkrijgen.

Verder wordt gezocht naar de waarde IDAT wat het begin van de daadwerkelijke afbeelding aangeeft. Deze waarde is altijd aanwezig in een png en komt altijd na de pHYs als deze aanwezig is. Op deze manier hoeft niet de complete afbeelding doorzocht te worden, mochten de fysieke afmetingen niet gespecificeerd zijn.


// get dpi from a png file (using a html5 file althought any type of png convertable to a bit array will work)
var reader = new FileReader();
reader.onload = function() {
 
// retrieve and convert the image to a bit array
var arrayBuffer = this.result;
var array = new Uint8Array(arrayBuffer);

       // loop through all bits   
       for (bit = 0; bit < array.length - 1; bit++) {
 
                // check for pHYs
                if (testForPHYs(array, bit)) {
                                  
                        // get dpi
                        var dpi = readDpi(array, index + 4);
    
                        // use / apply the found dpi
                        setDpi(dpi);

                        // break if found 
                        return;

                // check for IDAT
                } else if (testForIDAT(array, bit)) {

                        // break if found
                        return;
                }             
        }
}

// start the filereader once its loaded
reader.readAsArrayBuffer(file);
 
// test the bit at index + the 3 next bits 
function testForPHYs(array, index) {
              
        // test for pHYs in order
        if (array[index] == 112 &&              // p
           array[index + 1] == 72 &&    // H
           array[index + 2] == 89 &&    // Y
           array[index + 3] == 115) {   // s
 
                // found
                return true;
                     
        }
       
        // incorrect sequence, not found
        return false;
}

// test the bit at index + the 3 next bits 
function testForIDAT(array, index) {
              
        // test for IDAT in order
        if (array[index] == 73 &&               // I
           array[index + 1] == 68 &&    // D
           array[index + 2] == 65 &&    // A
           array[index + 3] == 84) {    // T
 
                // found
                return true;
                     
        }
       
        // incorrect sequence, not found
        return false;
}

// read the dpi (starting at the first bit after pHYs)   
function readDpi(array, index) {
       
        // read the next 4 bits and merge them using bitshifts
        var ppm =       (array[index] << 24) +
                        (array[index + 1] << 16) +
                        (array[index + 2] << 8) +
                        (array[index + 3]);

       // convert pixels per meter to dpi
        var dpi = ppm / 100 / 0.393700787;

        // return the dpi
        return dpi;
}

Bronnen

hexed

lib png

lib png pHYs


Andere blogartikelen

  • Waarom developers het zo leuk vinden bij ons

    Geschreven door: op woensdag 13 november 2019

    Bij ons op kantoor werkt een team van betrokken specialisten, waaronder 4 backend developers en 4 UX developers. Zij zorgen voor een belangrijk fundament binnen dit bedrijf. Een goede reden om te zorg ...

    Bekijk het artikel »
  • Beachvolleyballen voor het goede doel!

    Geschreven door: op vrijdag 25 oktober 2019

    Afgelopen vrijdag 11 oktober  hebben diverse betrokken specialisten uit ons team de handen ineen geslagen met een van onze opdrachtgevers. Samen met De Monchy International B.V. hebben we meegeda ...

    Bekijk het artikel »
  • Het gebruik van een Photoslider

    Geschreven door: op maandag 7 oktober 2019

    Ze zijn er in alle soorten en maten en staan meestal bovenaan een websitepagina. Dan heb ik het natuurlijk over photosliders. Zo bent u vast bekend met de traditionele foto die langzaam vervaagd en wa ...

    Bekijk het artikel »
Bel 072 5345 888
Onze Middelen en Technologieën
microsoft silver partner
Adobe partner
fd-gazellen-2018.jpg
Google analytics
partners-logo.jpg
Op de hoogte blijven?

Meld u aan voor de gratis nieuwsbrief om op de hoogte te blijven van onze activiteiten