language-agnostic image-manipulation

language agnostic - Tamaño de imagen proporcional



language-agnostic image-manipulation (6)

Aquí hay una función que he desarrollado para mi sitio, es posible que desee utilizar. Está basado en tu respuesta anterior.

Hace otras cosas, no solo el procesamiento de la imagen: elimine todo lo que sea innecesario .

<?php $thumb_width = 500; $thumb_height = 500; if ($handle = opendir(''to-do'')) { echo "Directory handle: $handle<br />"; echo "Files:<br /><br />"; /* This is the correct way to loop over the directory. */ while (false !== ($file = readdir($handle))) { if ( ($file != ".") && ($file != "..") ){ echo "$file"; $original_path = "to-do/" . $file; $source_image = ImageCreateFromJPEG( $original_path ); $thumb_width = $thumb_width; $thumb_height = $thumb_height; // Create the image, of the required size $thumbnail = imagecreatetruecolor($thumb_width, $thumb_height); if($thumbnail === false) { //creation failed -- probably not enough memory return null; } // Fill the image with a white color (this will be visible in the padding around the image, // if the aspect ratios of the image and the thumbnail do not match) // Replace this with any color you want, or comment it out for black. // I used grey for testing =) $fill = imagecolorallocate($thumbnail, 255, 255, 255); imagefill($thumbnail, 0, 0, $fill); // Compute resize ratio $hratio = $thumb_height / imagesy($source_image); $wratio = $thumb_width / imagesx($source_image); $ratio = min($hratio, $wratio); // If the source is smaller than the thumbnail size, // Don''t resize -- add a margin instead // (that is, dont magnify images) if ($ratio > 1.0) $ratio = 1.0; // Compute sizes $sy = floor(imagesy($source_image) * $ratio); $sx = floor(imagesx($source_image) * $ratio); // Compute margins // Using these margins centers the image in the thumbnail. // If you always want the image to the top left, set both of these to 0 $m_y = floor(($thumb_height - $sy) / 2); $m_x = floor(($thumb_width - $sx) / 2); // Copy the image data, and resample // If you want a fast and ugly thumbnail, replace imagecopyresampled with imagecopyresized if (!imagecopyresampled($thumbnail, $source_image, $m_x, $m_y, //dest x, y (margins) 0, 0, //src x, y (0,0 means top left) $sx, $sy,//dest w, h (resample to this size (computed above) imagesx($source_image), imagesy($source_image)) //src w, h (the full size of the original) ) { //copy failed imagedestroy($thumbnail); return null; } /* Set the new file name */ $thumbnail_file_name = $file; /* Apply changes on the original image and write the result on the disk */ ImageJPEG( $thumbnail, $complete_path . "done/" . $thumbnail_file_name ); unset($source_image); unset($thumbnail); unset($original_path); unset($targeted_image_size); echo " done<br />"; } } closedir($handle); } ?>

Tengo un pequeño problema para escalar mis imágenes a un tamaño predefinido adecuadamente. Me estaba preguntando, ya que es puramente matemática, si hay algún tipo de algoritmo lógico común que funciona en todos los idiomas (PHP, ActionScript, Javascript, etc.) para escalar las imágenes proporcionalmente.

Estoy usando esto en este momento:

var maxHeight = 300; var maxWidth = 300; var ratio:Number = height / width; if (height > maxHeight) { height = maxHeight; width = Math.round(height / ratio); } else if(width > maxWidth) { width = maxWidth; height = Math.round(width * ratio); }

Pero no funciona correctamente. Las imágenes se escalan proporcionalmente, por supuesto, pero el tamaño no se establece en 300 (ya sea en ancho o en altura). Tiene algún sentido, pero me preguntaba si existe una forma fácil de escalar imágenes proporcionalmente.


Así es como lo hago:

+ (NSSize) scaleHeight:(NSSize)origSize newHeight:(CGFloat)height { NSSize newSize = NSZeroSize; if ( origSize.height == 0 ) return newSize; newSize.height = height; CGFloat factor = ( height / origSize.height ); newSize.width = (origSize.width * factor ); return newSize; } + (NSSize) scaleWidth:(NSSize)origSize newWidth:(CGFloat)width { NSSize newSize = NSZeroSize; if ( origSize.width == 0 ) return newSize; newSize.width = width; CGFloat factor = ( width / origSize.width ); newSize.height = (origSize.height * factor ); return newSize; }


Dark Shikari lo tiene. Su solución, tal como se establece en la pregunta, fracasa porque no está estableciendo primero cuál de las dimensiones de dimenson es mayor y luego reduciendo ambas dimensiones en esa proporción mayor.

El uso de su solución actual de un análisis condicional y en serie de una posible violación dimensional y luego del otro no funcionará.

Tenga en cuenta también que si desea mejorar las imágenes, su solución actual no volará, y Dark Shikari lo hará nuevamente.


Yo recomendaría no escribir este código usted mismo; hay miríadas de detalles a nivel de píxel que tardan un tiempo serio en hacerlo bien. Use ImageMagick, es la mejor biblioteca de gráficos que existe.


bien hice esta función a escala proporcional, usa un ancho, una altura y, opcionalmente, el ancho / alto máximo que desea (depende del ancho y la altura)

function scaleProportional($img_w,$img_h,$max=50) { $w = 0; $h = 0; $img_w > $img_h ? $w = $img_w / $img_h : $w = 1; $img_h > $img_w ? $h = $img_h / $img_w : $h = 1; $ws = $w > $h ? $ws = ($w / $w) * $max : $ws = (1 / $h) * $max; $hs = $h > $w ? $hs = ($h / $h) * $max : $hs = (1 / $w) * $max; return array( ''width''=>$ws, ''height''=>$hs ); }

uso:

$getScale = scaleProportional(600,200,500); $targ_w = $getScale[''width'']; //returns 500 $targ_h = $getScale[''height'']; //returns 16,6666667


ratio = MIN( maxWidth / width, maxHeight/ height ); width = ratio * width; height = ratio * height;

Asegúrese de que todas las divisiones sean de coma flotante.