Determine the DPI of a PNG File using Javascript

Rodrigo Lucas
5 min readDec 24, 2023

--

Today’s blog post is about something important for anyone who works with digital images: how to find the physical dimensions of a PNG file and figure out its DPI.

We’ll start by giving a brief overview of the topic and explaining what physical dimensions and DPI are.

Then we’ll look at how PNG files are put together and how to find the pHYs chunk, which has information about the physical dimensions.

From there, we’ll talk about how to use the pHYs values to figure out DPI and what that number means. In the end, we’ll wrap up with a summary of the post’s main points.

Topics

  • Introduction
  • Understanding PNG files
  • Finding the pHYs chunk
  • Using the pHYs values to calculate DPI
  • Conclusion

Introduction

PNG files are a common format for graphics on the web and digital art. But if you’re working with PNG files for printing or displaying, you may need to know their size and DPI (dots per inch) to make sure you get the best results.

In this post, we’ll show you how to use the pHYs chunk to find the physical dimensions of a PNG file. We’ll also show you how to figure out the DPI of an image based on its physical size, so you can make high-quality prints or displays.

So, if you are a graphic designer, a photographer, or just interested in how PNG files work, keep reading to find out how to find the physical dimensions and DPI of your PNG files.

Understanding PNG files

PNG stands for “Portable Network Graphics.” It is a common image format used on the web that doesn’t lose any quality. PNG files don’t lose any image quality when compressed, unlike JPEG files. This makes them a very good option for digital art and graphics that need high resolution and transparency.

A PNG file is made up of a header and several different “chunks” of data. The header tells you about the file, like how big it is and what type it is. On the other hand, the chunks hold the actual image data as well as other information like the color profile and transparency.

The pHYs chunk, which stores the size of the image, is one of the most important parts of a PNG file. This is important for figuring out the DPI of the image correctly.

Overall, it’s important to know how a PNG file is put together and what its parts are if you want to work with and change these kinds of images correctly.

Finding the pHYs chunk

The pHYs chunk is a crucial component of a PNG file that stores the physical dimensions of the image. This includes the image’s pixel density and unit of measurement, which is necessary for accurately calculating the DPI.

To find the pHYs chunk using vanilla JavaScript, follow these steps:

  1. Load the PNG file into a buffer
  2. Parse the buffer to identify the pHYs chunk
  3. Read the pHYs chunk data to extract the pixel density and unit of measurement values

Here is a piece of code that shows how to find the pHYs chunk and get the data from it:

// Create an <input> element to select the PNG file
const fileInput = document.createElement('input');
fileInput.type = 'file';
document.body.appendChild(fileInput);

// Define the function to be called when the file is selected
fileInput.addEventListener('change', function(event) {
const file = event.target.files[0];

// Create an instance of the FileReader object to read the PNG file
const reader = new FileReader();

// Define the function to be called when the file is fully loaded
reader.addEventListener('load', function() {
const bytes = new Uint8Array(reader.result);

// Check if the file starts with the PNG header
if (bytes[0] !== 137 || bytes[1] !== 80 || bytes[2] !== 78 || bytes[3] !== 71 ||
bytes[4] !== 13 || bytes[5] !== 10 || bytes[6] !== 26 || bytes[7] !== 10) {
console.log('Invalid PNG file.');
return;
}

let offset = 8;
let pHYsFound = false;
let pixelsPerMeterX = 0;
let pixelsPerMeterY = 0;

// Parse the PNG header to find the pHYs chunk
while (offset < bytes.length) {
const chunkLength = (bytes[offset] << 24) | (bytes[offset + 1] << 16) |
(bytes[offset + 2] << 8) | bytes[offset + 3];
const chunkType = String.fromCharCode(bytes[offset + 4], bytes[offset + 5],
bytes[offset + 6], bytes[offset + 7]);

if (chunkType === 'pHYs') {
pixelsPerMeterX = (bytes[offset + 8] << 24) | (bytes[offset + 9] << 16) |
(bytes[offset + 10] << 8) | bytes[offset + 11];
pixelsPerMeterY = (bytes[offset + 12] << 24) | (bytes[offset + 13] << 16) |
(bytes[offset + 14] << 8) | bytes[offset + 15];
pHYsFound = true;
break;
}

offset += chunkLength + 12;
}

// Check if the pHYs chunk was found
if (!pHYsFound) {
console.log('pHYs chunk não encontrado.');
return;
}

// Display the values of pixels per meter horizontally and vertically
console.log('Pixels per meter (horizontal): ' + pixelsPerMeterX);
console.log('Pixels per meter (vertical): ' + pixelsPerMeterY);
});

// Read the contents of the file as an array of bytes
reader.readAsArrayBuffer(file);
});

Using the pHYs values to calculate DPI

The pHYs chunk in a PNG file provides crucial information about the physical dimensions of the image, including its resolution. By extracting the values from the pHYs chunk, we can calculate the DPI (dots per inch) of the image, which is a measure of its quality and suitability for printing or displaying.

To calculate DPI using the pHYs values, we can use the following formula:

DPI = (pixels per meter / physical dimension) * 0.0254

where:

  • pixels per meter is the pixel density value from the pHYs chunk multiplied by 39.37 (to convert from dots per inch to dots per meter)
  • physical dimension is the image width or height, depending on the unit of measurement value in the pHYs chunk (0 for width, 1 for height)
  • 0.0254 is the conversion factor for meters to inches

For example, if the pHYs chunk contains a pixel density value of 300 DPI and a unit of measurement value of 0 (indicating that the physical dimension is the image width), and the image has a width of 1000 pixels, we can calculate the DPI as follows:

pixels per meter = 300 * 39.37 = 11811

physical dimension = 1000 (width)

DPI = (11811 / 1000) * 0.0254 = 300

The resulting DPI value of 300 indicates that the image has a high resolution and is suitable for printing at a high quality. On the other hand, if the calculated DPI is low (e.g. below 72 DPI), it may result in poor print quality and pixelated images.

Conclusion

In conclusion, knowing the exact size and DPI of a PNG picture is a necessary approach for producing high-quality prints or other output and
I hope it’s guide on finding the DPI and dimensions of a PNG file has been of use to you.

--

--

Rodrigo Lucas

Brazilian 🇧🇷 Carioca. A great lover of culture 🌱, travel ✈️ and technology 💻