Estou tentando fazer uma programação dinâmica com base no número de caracteres em uma frase. Qual letra do alfabeto inglês ocupa mais pixels na tela?
Estou tentando fazer uma programação dinâmica com base no número de caracteres em uma frase. Qual letra do alfabeto inglês ocupa mais pixels na tela?
Respostas:
Hmm, vamos ver:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
cccccccccccccccccccccccccccccccccccccccc
ddddddddddddddddddddddddddddddddddddddd
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
ffffffffffffffffffffffffffffffffffffffff
gggggggggggggggggggggggggggggggggggggg
hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
llllllllllllllllllllllllllllllllllllllll
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
oooooooooooooooooooooooooooooooooooooooo
pppppppppppppppppppppppppppppppppppppppp
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr
ssssssssssssssssssssssssssssssssssssssss
tttttttttttttttttttttttttttttttttttttttt
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD
EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ
KKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKKK
LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP
QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT
UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY
ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ
W vence.
Claro, este é um experimento empírico bobo. Não existe uma resposta única para qual letra é mais larga. Depende da fonte. Portanto, você terá que fazer um experimento empírico semelhante para descobrir a resposta para o seu ambiente. Mas o fato é que a maioria das fontes segue as mesmas convenções e o capital W será o mais amplo.
Gist com essas larguras de caracteres em um formato de proporção (W = 100) capturado aqui usando esta fonte de exemplo específica:
https://gist.github.com/imaurer/d330e68e70180c985b380f25e195b90c
Seguindo a resposta incrivelmente prática de Ned Batchelder, porque eu vim aqui pensando em dígitos:
000000000000000000000000000000000000000000
1111111111111111111111111111111111111111
2222222222222222222222222222222222222222
3333333333333333333333333333333333333333
4444444444444444444444444444444444444444
5555555555555555555555555555555555555555
6666666666666666666666666666666666666666
7777777777777777777777777777777777777777
8888888888888888888888888888888888888888
99999999999999999999999999999999999999
font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
font-size: 15px;
Oh, que a Apple, sempre tentando ser um pouco diferente pouco ....
font-variant-numeric
: números proporcionais permitem larguras diferentes, tanto no glifo quanto no espaçamento, enquanto os números tabulares devem seguir regras semelhantes às fontes monoespaçadas.
Que tal uma solução programática?
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 < capsIndex + 26; 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);
}
}
for(var i = smallIndex; i < smallIndex + 26; 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';
O capital "M" é convencionalmente o mais amplo.
Dependendo da sua plataforma, pode haver uma maneira de "getWidth" de uma string ou da função DrawText () de alguma forma com uma propriedade width.
Eu faria um algortime simples que utilizasse a fonte necessária e, em seguida, percorria o alfabet e o armazenava em uma pequena configuração ou apenas o calculava na inicialização como um loop de A a Z não é tão difícil.
Também depende da fonte. Eu fiz isso há 1 ou 2 anos com Processing e Helvetica e é ILJTYFVCPAXUZKHSEDORGNBQMW na ordem de pixels crescentes. A idéia é desenhar o texto em uma tela com a fonte que você está vendo, contar os pixels e classificar com um HashMap ou dicionário.
Obviamente, isso pode não ser diretamente relevante para o seu uso, pois calcula a área de pixels em vez de apenas a largura. Também pode ser um pouco exagerado.
void setup() {
size(30,30);
HashMap hm = new HashMap();
fill(255);
PFont font = loadFont("Helvetica-20.vlw");
textFont(font,20);
textAlign(CENTER);
for (int i=65; i<91; i++) {
background(0);
text(char(i),width/2,height-(textDescent()+textAscent())/2);
loadPixels();
int white=0;
for (int k=0; k<pixels.length; k++) {
white+=red(pixels[k]);
}
hm.put(char(i),white);
}
HashMap sorted = getSortedMap(hm);
String asciiString = new String();
for (Iterator<Map.Entry> i = sorted.entrySet().iterator(); i.hasNext();) {
Map.Entry me = (Map.Entry)i.next();
asciiString += me.getKey();
}
println(asciiString); //the string in ascending pixel order
}
public HashMap getSortedMap(HashMap hmap) {
HashMap map = new LinkedHashMap();
List mapKeys = new ArrayList(hmap.keySet());
List mapValues = new ArrayList(hmap.values());
TreeSet sortedSet = new TreeSet(mapValues);
Object[] sortedArray = sortedSet.toArray();
int size = sortedArray.length;
// a) Ascending sort
for (int i=0; i<size; i++) {
map.put(mapKeys.get(mapValues.indexOf(sortedArray[i])), sortedArray[i]);
}
return map;
}
Arial 30px no Chrome - W vence .
Uma solução para calcular as larguras de fontes um pouco como a solução postada por xxx foi postada por Alex Michael em seu blog (o que engraçado é que me ligou aqui).
Resumo:
Correio original: http://alexmic.net/letter-pixel-count/
Código:
# -*- coding: utf-8 -*-
from __future__ import division
import os
from collections import defaultdict
from math import sqrt
from PIL import Image, ImageDraw, ImageFont
# Make a lowercase + uppercase alphabet.
alphabet = 'abcdefghijklmnopqrstuvwxyz'
alphabet += ''.join(map(str.upper, alphabet))
def draw_letter(letter, font, save=True):
img = Image.new('RGB', (100, 100), 'white')
draw = ImageDraw.Draw(img)
draw.text((0,0), letter, font=font, fill='#000000')
if save:
img.save("imgs/{}.png".format(letter), 'PNG')
return img
def count_black_pixels(img):
pixels = list(img.getdata())
return len(filter(lambda rgb: sum(rgb) == 0, pixels))
def available_fonts():
fontdir = '/Users/alex/Desktop/English'
for root, dirs, filenames in os.walk(fontdir):
for name in filenames:
path = os.path.join(root, name)
try:
yield ImageFont.truetype(path, 100)
except IOError:
pass
def letter_statistics(counts):
for letter, counts in sorted(counts.iteritems()):
n = len(counts)
mean = sum(counts) / n
sd = sqrt(sum((x - mean) ** 2 for x in counts) / n)
yield letter, mean, sd
def main():
counts = defaultdict(list)
for letter in alphabet:
for font in available_fonts():
img = draw_letter(letter, font, save=False)
count = count_black_pixels(img)
counts[letter].append(count)
for letter, mean, sd in letter_statistics(counts):
print u"{0}: {1:.2f} ± {2:.2f}".format(letter, mean, sd)
if __name__ == '__main__':
main()
Isso dependerá da fonte. Eu criaria um pequeno programa em uma linguagem de programação com a qual você se sinta mais confortável, onde você desenha cada letra do alfabeto em um bitmap de tamanho m. Inicialize cada pixel com branco. Depois conte o número de pixels brancos depois de desenhar cada letra e salve esse número. O número mais alto encontrado é o que você procura.
EDIT: se você está realmente interessado em qual deles ocupa o maior retângulo (mas parece que você está realmente depois disso, não os pixels), você pode usar várias chamadas de API para encontrar o tamanho, mas isso depende sua linguagem de programação. Em Java, por exemplo, você usaria a classe FontMetrics.
Eu sei que a resposta aceita aqui é W, W é para WIN.
No entanto, nesse caso, W também é para Largura. O estudo de caso utilizado empregou um teste simples de largura para examinar pixels, mas era apenas a largura, não a contagem total de pixels. Como um exemplo simples de contador, a resposta aceita pressupõe que O e Q ocupam a mesma quantidade de pixels, mas ocupam apenas a mesma quantidade de espaço.
Assim, W ocupa mais espaço . Mas, são todos os pixels que está rachado?
Vamos pegar alguns dados empíricos. Criei imagens imgur a partir dos seguintes B, M e W. Analisei sua contagem de pixels (veja abaixo), eis os resultados:
B: 114 pixels
M: 150 pixels
W: 157 pixels
Aqui está como eu os coloquei na tela e analisei os dados brutos de pixel das imagens.
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>
Quer saber a verdadeira glifo mais longo, não apenas supondo?
E não estou falando apenas das letras, dígitos e símbolos comuns (!, @ E assim por diante). Quero dizer o glifo mais longo em todos os 32.834 caracteres de UTF-16.
Comecei com a resposta do @NK que tinha uma solução programática e fiz algumas pequenas modificações:
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';
Depois de executar isso e esperar (e esperar), ele fornece a saída ௌ won
.
E aí está, o personagem mais longo do UTF-32! Observe que em algumas fontes o glifo mais longo é ﷽, mas as outras fontes (especialmente as monoespaçadas) se sobrepõem aos caracteres, como acontece com a fonte que o programa leva em consideração.