php - imagemagick convert
Cómo detener las imágenes de rotación automática de iMagick de PHP basadas en datos de ''orientación'' de EXIF (4)
"Sin embargo, iMagick, cuando se construyó con esta imagen, automáticamente la gira 90 grados CCW adicionales según [Orientación] => 6 (¡creo!)".
El problema es en realidad lo opuesto a eso. Imagick no gira automáticamente la imagen. Solo lo está viendo correctamente en otro software o en su navegador web porque esos programas lo giran automáticamente según la información EXIF. Ciertas operaciones en Imagick harán que pierda la información EXIF correcta (copiando la imagen, thumbnailImage (), stripImage () y otras manipulaciones). Entonces, lo que debe hacer en ese caso es rotar físicamente la imagen.
La respuesta de ajmicek es buena, pero podría mejorarse un poco utilizando las funciones integradas de Imagick en lugar de las funciones EXIF de PHP. Además, ese fragmento de código parece haber sido parte de una clase, por lo que no puede usarse como una función separada tal como es. También es una buena idea establecer la orientación EXIF correcta con setImageOrientation () después de girarlo.
// Note: $image is an Imagick object, not a filename! See example use below.
function autoRotateImage($image) {
$orientation = $image->getImageOrientation();
switch($orientation) {
case imagick::ORIENTATION_BOTTOMRIGHT:
$image->rotateimage("#000", 180); // rotate 180 degrees
break;
case imagick::ORIENTATION_RIGHTTOP:
$image->rotateimage("#000", 90); // rotate 90 degrees CW
break;
case imagick::ORIENTATION_LEFTBOTTOM:
$image->rotateimage("#000", -90); // rotate 90 degrees CCW
break;
}
// Now that it''s auto-rotated, make sure the EXIF data is correct in case the EXIF gets saved with the image!
$image->setImageOrientation(imagick::ORIENTATION_TOPLEFT);
}
Ejemplo de uso:
$image = new Imagick(''my-image-file.jpg'');
autoRotateImage($image);
// - Do other stuff to the image here -
$image->writeImage(''result-image.jpg'');
Actualmente, estoy trabajando con PHP e iMagick para desarrollar una aplicación web de impresión de pósteres.
Esta es la imagen de ejemplo que estoy usando para probar las características de carga / edición de imágenes de la aplicación:
La imagen contiene los siguientes datos EXIF:
[FileName] => 1290599108_IMG_6783.JPG
[FileDateTime] => 1290599109
[FileSize] => 4275563
[FileType] => 2
[MimeType] => image/jpeg
[SectionsFound] => ANY_TAG, IFD0, THUMBNAIL, EXIF, INTEROP, MAKERNOTE
[COMPUTED] => Array
(
[html] => width="3504" height="2336"
[Height] => 2336
[Width] => 3504
[IsColor] => 1
[ByteOrderMotorola] => 0
[CCDWidth] => 22mm
[ApertureFNumber] => f/5.6
[UserComment] =>
[UserCommentEncoding] => UNDEFINED
[Thumbnail.FileType] => 2
[Thumbnail.MimeType] => image/jpeg
)
[Make] => Canon
[Model] => Canon EOS 30D
[Orientation] => 6
[XResolution] => 72/1
[YResolution] => 72/1
[ResolutionUnit] => 2
[DateTime] => 2009:08:31 08:23:49
[YCbCrPositioning] => 2
[Exif_IFD_Pointer] => 196
Sin embargo, iMagick, cuando se construyó con esta imagen, automáticamente la gira 90 grados CCW adicionales según [Orientation] => 6
(¡creo!). Resultando en esto ...
Lo que me gustaría saber es ...
¿Cómo puedo mantener la orientación original de la imagen que se ve en la parte superior de la página? ¿Y es posible deshabilitando la rotación automática realizada por iMagick?
Muchas gracias
ACTUALIZACIÓN: Aquí está la solución que encontré ... Arreglará la orientación basada en la orientación en los datos EXIF
public function fixOrientation() {
$exif = exif_read_data($this->imgSrc);
$orientation = $exif[''Orientation''];
switch($orientation) {
case 6: // rotate 90 degrees CW
$this->image->rotateimage("#FFF", 90);
break;
case 8: // rotate 90 degrees CCW
$this->image->rotateimage("#FFF", -90);
break;
}
}
Buen comienzo, algunas adiciones para hacer que la función sea más robusta. Primero, el caso 3 ocurre cuando la imagen aparece al revés. Hay una GRAN ilustración de los diferentes códigos de orientación de Calvin Hass . Es posible que la información de orientación aparezca en una parte diferente de la matriz exif_read_data
(según el modelo de cámara, creo), por lo que he tratado de tener eso en cuenta en mi código de ejemplo.
Algo como esto:
public function fixOrientation() {
$exif = exif_read_data($this->imgSrc);
if( isset($exif[''Orientation'']) )
$orientation = $exif[''Orientation''];
elseif( isset($exif[''IFD0''][''Orientation'']) )
$orientation = $exif[''IFD0''][''Orientation''];
else
return false;
switch($orientation) {
case 3: // rotate 180 degrees
$this->image->rotateimage("#FFF", 180);
break;
case 6: // rotate 90 degrees CW
$this->image->rotateimage("#FFF", 90);
break;
case 8: // rotate 90 degrees CCW
$this->image->rotateimage("#FFF", -90);
break;
}
}
La transformación y guardar te deja sin la información EXIF anterior, incluida la Orientation
. La falta de Orientation
en la imagen transformada evitará que el procesamiento posterior intente "corregir" las cosas girando nuevamente. Me gustaría que Imagick tuviera soporte para ImageMagick''s -auto-orient
, pero bueno.
Ah, también: la rotación es una operación con pérdida (a menos que use jpegtran), por lo que debe intentar hacerlo solo junto con un cambio de tamaño u otra transformación.
Este código en la excelente respuesta de orrd requiere iMagick versión 6.3+:
$ image-> setImageOrientation (imagick :: ORIENTATION_TOPLEFT);
Funciona perfectamente y cuida las diferencias de orientación os / dispositivo. No trabajaría con 6.2.
Yo había codificado para obtener el dispositivo. Aquí por si alguien lo necesita.
$ua = $_SERVER[''HTTP_USER_AGENT''];
$strcut = stristr($ua, ''('')."<br>";
$textlen = strpos($strcut,";");
$deviceos = substr($strcut,1,($textlen-1));
echo "Device O/S: * $deviceos"."<br>";
Pruebe Imagick::setImageOrientation
. Experimenta con las constantes disponibles .