Which letter of the English alphabet takes up most pixels?

Viewed 111195

I am trying to do some dynamic programming based on the number of characters in a sentence. Which letter of the English alphabet takes up the most pixels on the screen?

15 Answers

I know the accepted answer here is W, W is for WIN.

However, in this case, W is also for Width. The case study used employed a simple width test to examine pixels, but it was only the width, not the total pixel count. As an easy counter example, the accepted answer assumes that O and Q take up the same amount of pixels, yet they only take up the same amount of space.

Thus, W takes up the most space. But, is it all the pixels it's cracked up to be?

Let's get some empirical data. I created imgur images from the following B, M and W. I then analyzed their pixel count (see below), here are the results:

B : 114 pixels

M : 150 pixels

W : 157 pixels

Here is how I fed them into canvas and analyzed the raw pixel data from the images.

var imgs = {
 B : "//i.imgur.com/YOuEPOn.png",
 M : "//i.imgur.com/Aev3ZKQ.png",
 W : "//i.imgur.com/xSUwE7w.png"
};
window.onload = function(){
  for(var key in imgs){(function(img,key){
    var Out = document.querySelector("#"+key+"Out");
    img.crossOrigin = "Anonymous";
    img.src=imgs[key];
    img.onload = function() {
      var canvas = document.querySelector('#'+key);
      (canvas.width = img.width,canvas.height = img.height);
      var context = canvas.getContext('2d');
      context.drawImage(img, 0, 0);
      var data = context.getImageData(0, 0, img.width, img.height).data;
      Out.innerHTML = "Total Pixels: " + data.length/4 + "<br>";
      var pixelObject = {};
      for(var i = 0; i < data.length; i += 4){
        var rgba = "rgba("+data[i]+","+data[i+1]+","+data[i+2]+","+data[i+3]+")";
       pixelObject[rgba] = pixelObject[rgba] ? pixelObject[rgba]+1 : 1;
      }
      Out.innerHTML += "Total Whitespace: " + pixelObject["rgba(255,255,255,255)"] + "<br>";
      Out.innerHTML += "Total Pixels In "+ key +": " + ((data.length/4)-pixelObject["rgba(255,255,255,255)"]) + "<br>";
    };
  })(new Image(),key)}
};
<table>
<tr>
  <td>
    <canvas id="B" width="100%" height="100%"></canvas>
  </td>
  <td id="BOut">
  </td>
</tr>
<tr>
  <td>
    <canvas id="M" width="100%" height="100%"></canvas>
  </td>
  <td id="MOut">
  </td>
</tr>
<tr>
  <td>
    <canvas id="W" width="100%" height="100%"></canvas>
  </td>
  <td id="WOut">
  </td>
</tr>
</table>

Want to know the real longest glyph, not just guessing?
And I'm not just talking about the letters, digits and common symbols (!, @ and so on). I mean the longest glyph in all the 32,834 characters of UTF-16.
So I started with answer by @NK that had a programmatic solution to it, and made a modification:

var capsIndex = 65;
var smallIndex = 97;
var div = document.createElement('div');
div.style.float = 'left';
document.body.appendChild(div);
var highestWidth = 0;
var elem;

for(var i = capsIndex; i < 32834; i++) {
    div.innerText = String.fromCharCode(i);
    var computedWidth = window.getComputedStyle(div, null).getPropertyValue("width");
    if(highestWidth < parseFloat(computedWidth)) {
        highestWidth = parseFloat(computedWidth);
        elem = String.fromCharCode(i);
    }
}
div.innerHTML = '<b>' + elem + '</b>' + ' won';

After running this and waiting (and waiting), it gives the output ௌ won.
And there you have it, the longest character in UTF-32! Note that on most fonts the longest glyph is ﷽, but some fonts (especially monospace ones) overlap the characters, as with the font that the program was run with.

This code will get widths for all characters as array:

        const alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        var widths = [];
        
        var div = document.createElement('div');
        div.style.float = 'left';
        document.body.appendChild(div);
        
        var highestObservedWidth = 0;
        // widest characters (not just one)
        var answer = '';
        
        for (var i = 0; i < alphabet.length; i++) {
            div.innerText = alphabet[i];
            var computedWidthString = window.getComputedStyle(div, null).getPropertyValue("width");
            var computedWidth = parseFloat(computedWidthString.slice(0, -2));
    //      console.log(typeof(computedWidth));
            widths[i] = computedWidth;
            if(highestObservedWidth == computedWidth) {
                answer = answer + ', ' + div.innerText;
            }
            if(highestObservedWidth < computedWidth) {
                highestObservedWidth = computedWidth;
                answer = div.innerText;
            }
        }
        if (answer.length == 1) {
            div.innerHTML = ' Winner: ';
        } else {
            div.innerHTML = ' Winners: ';
        }
        div.innerHTML = div.innerHTML + answer + '.';
        console.log(widths.sort((a, b) => a - b));

Or if you want to have a map of widths, containing more than just alpha(numeric) characters like described above (like I needed in a non-browser environment)

const chars = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "!", "\"", "#", "$", "%", "'", "(", ")", "*", "+", ",", "-", ".", "/", ":", ";", "=", "?", "@", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "|", "}", "~", " ", "&", ">", "<"]

const test = document.createElement('div')
test.id = "Test"
document.body.appendChild(test)
test.style.fontSize = 12

const result = {}

chars.forEach(char => {
  let newStr = ""
  for (let i = 0; i < 10; i++) {
    if (char === " ") {
      newStr += "&nbsp;"
    } else {
      newStr += char
    }  
  }
  test.innerHTML = newStr
  const width = (test.clientWidth)
  result[char] = width / 10
})

console.log('RESULT:', result)
#Test
{
    position: absolute;
    /* visibility: hidden; */
    height: auto;
    width: auto;
    white-space: nowrap; /* Thanks to Herb Caudill comment */
}

Related