使用 PHP 进行无损图像旋转
Posted
技术标签:
【中文标题】使用 PHP 进行无损图像旋转【英文标题】:Lossless image rotate with PHP 【发布时间】:2012-10-15 13:53:31 【问题描述】:我一直在开发一个系统来旋转上传的图像。该算法的工作原理如下:
1) User uploads a jpeg. It gets saved as a PNG
2) Link to the temp png is returned to the user.
3) The user can click 90left,90right, or type in N degrees to rotate
4) The png is opened using
$image = imagecreatefrompng("./fileHERE");
5) The png is rotated using
$imageRotated = imagerotate($image,$degrees,0);
6) The png is saved and the link returned to the user.
7) If the user wishes to rotate more go back to step 3 operating on the newly
saved temporary PNG,
else the changes are commited and the final image is saved as a jpeg.
这在左右旋转 90 度时效果很好。用户可以无限旋转多次而不会损失任何质量。问题是当用户尝试旋转 20 度(或其他非 90 的倍数)时。当旋转 20 度时,图像会稍微旋转,并形成一个黑框来填充需要填充的区域。由于图像(带有黑框)保存为 png,下一次旋转 20 度会将图像(带有黑框)再旋转 20 度,并形成另一个黑框来填补空白。长话短说,如果你这样做到 360 度,你将在一个非常小的剩余图像周围有一个大黑框。即使您放大并裁剪黑框,也会有明显的质量损失。
有什么办法可以避免黑匣子? (服务器没有安装imagick)
【问题讨论】:
bugs.php.net/bug.php?id=25303 不,没有。图像必须有方角,因为标量成像就是这样工作的,你必须用一些东西填充它。如果你旋转 20 度,那么你决定你真的要旋转 40 度,你必须从基础图像重新开始,否则图像将不可避免地在后续操作中衰减。对此你几乎无能为力。 @hakre - 由于这个原因,我正在处理 PNG,而不是 JPEG @DaveRnadom - 谢谢。做出回答,我会给你点赞和赞誉。为什么旋转 90 度不会导致黑盒或丢失? @user974896:我不明白你的推理,因为 PNG 没有无损旋转。使用 JPEG 至少在某些情况下会出现 - 至少在技术上是这样(目前在 GD 中还没有)。 【参考方案1】:始终存储未修改的源文件,并在旋转时使用原始源文件旋转度数。所以 20 度 + 20 度,意味着将源旋转 40 度。
-
用户上传 JPEG。
用户可以点击“左90”、“右90”,或者输入N度进行旋转。
使用
打开 png$image = imagecreatefromjpeg("./source.jpg");
png 被旋转...
// If this is the first time, there is no rotation data, set it up
if(!isset($_SESSION["degrees"])) $_SESSION["degrees"] = 0;
// Apply the new rotation
$_SESSION["degrees"] += $degrees;
// Rotate the image
$rotated = imagerotate($image, $_SESSION["degrees"], 0);
// Save the image, DO NOT MODIFY THE SOURCE FILE!
imagejpeg($rotated, "./last.jpg");
// Output the image
header("Content-Type: image/jpeg");
imagejpeg($rotated);
如果用户希望旋转更多,则返回步骤 3,否则将 last.jpg 作为最终文件并销毁 $_SESSION["degrees"]
参数。
【讨论】:
以上是关于使用 PHP 进行无损图像旋转的主要内容,如果未能解决你的问题,请参考以下文章