我试着用php自动旋转一些压缩文件中的图片。对于自动旋转,我使用的是Exif:图片的方向信息。
代码确实工作,但我有一些图像的问题,似乎有错误的exif信息。我有这个问题,只有与图像采取的iPhone。
我的准则的作用:
1.把图片从拉链里拉出来
1.保存这pic在一个临时文件为.png处理
1.用1中的图片字符串初始化一个imagick对象。
1.检查pic是否为png
- is png:通过帮助器类PNGMetadata读取exif方向
1.不是png:使用imagick imageproperty得到exif方向
1.调用autoRotateImage将图片转到正确的方向
1.保存原始方向以备后用(我正在将原始方向保存在数据库中以供调试)
函数“autoRotateImage”仅处理exif方向并对每个方向执行正确的步骤。
PHP代码的组成部分:
try{
$img_content = $zip->getFromIndex($zip->locateName($img->getAttribute('xlink:href')));
$tmpPic = tempnam(sys_get_temp_dir(), $img->getAttribute('xlink:href'));
file_put_contents($tmpPic,$img_content);
$imagick_img = new \Imagick();
$imagick_img->readImageBlob($img_content);
if (PNGMetadata::isPNG($tmpPic)){
$png_metadata = new PNGMetadata($tmpPic);
$orientation_arr[$img->getAttribute('xlink:href')] = $png_metadata->get('exif:IFD0:Orientation');
$org_orientation = $png_metadata->get('exif:IFD0:Orientation');
}else{
$orientation_arr[$img->getAttribute('xlink:href')] = intval($imagick_img->getImageProperty('Exif:Orientation'));
$org_orientation = intval($imagick_img->getImageProperty('Exif:Orientation'));
}
autoRotateImage($imagick_img,new \Imagick(),(isset($manualOrientation[$img->getAttribute('xlink:href')]) ? $manualOrientation[$img->getAttribute('xlink:href')] : $org_orientation));
$imagick_img->clear();
unlink($tmpPic);
}catch(Exception $e){
if(isset($imagick_img)){$imagick_img->clear();}
if(isset($tmpPic)){unlink($tmpPic);}
}
自动旋转图像功能:
function autoRotateImage(&$image, $imagick, $orientation) {
switch($orientation) {
case $imagick::ORIENTATION_BOTTOMRIGHT: //3
$image->rotateimage("#000", 180); // rotate 180 degrees
break;
case $imagick::ORIENTATION_BOTTOMLEFT: //4
$image->flipImage(); // mirror vertical
break;
case $imagick::ORIENTATION_RIGHTTOP: //6
$image->rotateimage("#000", 90); // rotate 90 degrees CW
break;
case $imagick::ORIENTATION_LEFTTOP: //5
$image->transverseImage(); // horizontal mirror image by reflecting the pixels around the central y-axis while rotating them 270-degrees.
break;
case $imagick::ORIENTATION_LEFTBOTTOM: //8
$image->rotateimage("#000", 270); // rotate 270 degrees CW
break;
case $imagick::ORIENTATION_RIGHTBOTTOM: //7
$image->transverseImage(); //horizontal mirror image by reflecting the pixels around the central y-axis while rotating them 270-degrees.
$image->rotateimage("#000", -180); // rotate 180 degrees CCW
break;
case $imagick::ORIENTATION_TOPLEFT: //1
//Nothing to do
break;
case $imagick::ORIENTATION_TOPRIGHT: //2
$image->transverseImage(); //horizontal mirror image by reflecting the pixels around the central y-axis while rotating them 270-degrees.
$image->rotateimage("#000", 90); // rotate 90 degrees CW
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);
}
类“PNGMetadata”来自其他用户:https://github.com/joserick/PNGMetadata
所以..此代码适用于90%的处理图像,除了一些iPhone图像。当前案例:Exif方向显示为5(在y轴上镜像并顺时针旋转270),但它应该为7(在y轴上镜像并顺时针旋转90)
也许有人知道如何处理这些案件?
我已经尝试过以其他形式获取exif信息,但结果每次都是一样的。还有一个命令行exif阅读器从错误的图像中读到了错误的exif方向。
我需要一种方法来修复错误的方向。
1条答案
按热度按时间osh3o9ms1#
看起来imagick函数“transverseImage()”并不像aspected那样工作..我不知道它的确切功能,但我认为它的行为不符合描述..
描述说“创建一个水平镜像反射像素周围的中心y轴,同时旋转他们270度。"对我来说,这意味着,图像得到镜像,然后旋转270°CW。但图像将错误旋转后,该函数。
我尝试将“Imagick::flopImage”与rotateImage(270)结合使用,得到了不同的结果。
简短:我用flopImage + rotateImage替换了transverseImage,现在看来,图像旋转正确。