2011-02-22 16 views
5

Actualmente estoy usando blobstore para generar miniaturas para imágenes, sin embargo, me gusta almacenar las dimensiones de la miniatura en la etiqueta img, como es una buena práctica y ayuda a acelerar el procesamiento y hace que una página cargada parcialmente se vea un poco más agradable.App Engine: Cálculo de las dimensiones de las miniaturas que se generarán al publicar miniaturas de blobstore

¿Cómo puedo calcular las dimensiones de una miniatura generada por la librería de blob, conociendo solo las dimensiones de la imagen original?

Mis intentos anteriores no han sido muy precisos, la mayoría de las veces están desactivadas por un píxel o dos (probablemente debido al redondeo).

Entiendo que ir a la miniatura y usar la API de imágenes para verificar las dimensiones funcionaría, pero creo que es ineficiente.

Aquí está el código que uso para calcularlo en este momento, sin embargo, ocasionalmente está desactivado en un píxel, lo que hace que el navegador estire ligeramente la imagen, causando que cambie el tamaño de los artefactos y sea menos eficiente.

from __future__ import division 
def resized_size(original_width, original_height, width, height): 
    original_ratio = float(original_width)/float(original_height) 
    resize_ratio = float(width)/float(height) 
    if original_ratio >= resize_ratio: 
     return int(width), int(round(float(width)/float(original_ratio))) 
    else: 
     return int(round(float(original_ratio) * float(height))), int(height) 

¡La precisión es muy importante!

+1

¡Buena pregunta!¿Qué fórmula intentó y en qué situaciones estaba mal? –

+0

@systempuntoout, no los estoy generando, la API de publicación de imágenes de Google sí lo está, y no proporciona dimensiones. @Nick Johnson, actualicé mi pregunta con el código que estoy usando actualmente. –

Respuesta

4

Veo el problema. La razón es que la falta de C se usa para calcular las dimensiones. Python no tiene una implementación rint equivalente ya que fue tomada por Rossum en 1.6:

http://markmail.org/message/4di24iqm7zhc4rwc

Su único recurso en este momento es poner en práctica su propio rint en Python.

rint de forma predeterminada hace una ronda de "ronda a ronda" vs pitones que hace algo más. Aquí es una implementación simple (sin gastos de envío de + inf inf caso extremo, etc.)

import math 

def rint(x): 
    x_int = int(x) 
    x_rem = x - x_int # this is problematic 
    if (x_int % 2) == 1: 
    return round(x) 
    else: 
    if x_rem <= 0.5: 
     return math.floor(x) 
    else: 
     return math.ceil(x) 

El código anterior es la forma en que debe aplicarse en teoría. El problema está en x_rem. x - x_int debería obtener el componene fraccional pero en su lugar puede obtener la fracción + delta . Así que usted puede intentar añadir umbral si desea

import math 

def rint(x): 
    x_int = int(x) 
    x_rem = x - x_int 
    if (x_int % 2) == 1: 
    return round(x) 
    else: 
    if x_rem - 0.5 < 0.001: 
     return math.floor(x) 
    else: 
     return math.ceil(x) 

Por aquí. Codifiqué un umbral de 0.001. El umbral en sí mismo es problemático. Supongo que realmente necesita jugar con la implementación de rint y ajustarlo a su aplicación y ver qué funciona mejor. ¡Buena suerte!

+0

No estoy familiarizado con el rint, ¿cómo lo implementaría en Python? –

0

Suponiendo que tiene una imagen original de 1600x1200 y desea obtener una miniatura de tamaño 800, , el resultado esperado es una imagen de 800x600. Para calcular esto, puede hacer lo siguiente:

// In Java 
double aspectRatio = originalWidth/originalHeight; 
output_width = 800; 
output_height = (int)Math.round(800.0/aspectRatio); 

Veamos si esto funciona con las cajas degeneradas. Supongamos que tiene un original de 145x111 y desea obtener una miniatura de tamaño 32.

aspectRatio == 1.3063063063063063 
output_width == 32 
output_height == Math.round(32.0/1.3063063063063063) == 24 

Puede hacer algo similar para imágenes orientadas al retrato.

Cuestiones relacionadas