有没有一种方法可以告诉浏览器遵守JPEG的Exif方向?

56

我知道浏览器禁用了JPG文件的自动旋转功能。

它们无法启用此功能,因为这会破坏某些网站的布局。

是否有CSS属性或JavaScript代码可以实现此功能?还是有其他解决方案?或者可能目前还不存在解决此问题的方法?


2
当前的CSS规范忽略了EXIF数据。可能的解决方法是,通过脚本动态设置IMG元素的方向样式,基于预处理的图片文件名,其中包含一个后缀来指示正确的方向。例如:使用简单的"a","b","c","d"分别表示0度,90度,-90度和180度。 - Jay
谢谢您的提示/想法。但这仍然需要预处理。最好的方法是使用一些CSS属性来告诉浏览器尊重EXIF方向。我想响应将在浏览器代码中。 - Marc MAURICE
1
据我所知,iOS Safari可以理解EXIF方向信息,至少可以从使用iOS设备拍摄的照片中了解。 - Pointy
我认为最好的答案在这里:https://dev59.com/Z2Ij5IYBdhLWcg3wHh3_#40867559 - sstauross
7个回答

35

CSS image-orientation: from-image

从规范https://www.w3.org/TR/css4-images/#the-image-orientation中得知:

6.2. 图片在页面上的方向:‘image-orientation’属性

image-orientation: from-image

from-image: 如果图片有元数据(如EXIF)指定方向,则此值计算为元数据所需的角度,以正确定位图像。如果需要,将按照上述 为值 的描述对此角度进行四舍五入和归一化处理。如果没有指定方向,则此值计算为 ‘0deg’。

匹配Chrome问题:https://bugs.chromium.org/p/chromium/issues/detail?id=158753

但是这项技术的浏览器支持还未成熟:https://developer.mozilla.org/en/docs/Web/CSS/image-orientation#Browser_compatibility

通过JS旋转

有一个JS代码片段可以实现旋转:https://gist.github.com/runeb/c11f864cd7ead969a5f0

我的结论

我认为使用像imagemagick这样的工具在服务器上旋转图像的开销过大。

浏览器可以旋转图像,但Web应用程序需要明确地给出旋转建议。

可以通过以下方式在浏览器中显式地进行旋转:https://dev59.com/c2gt5IYBdhLWcg3wwwO-#11832483


5
令人惊讶的是,如果您查看指向JPEG图像本身的直接URL,则所有浏览器都会正确显示它。但是,当您将该图像设置为元素的背景时,它突然颠倒或侧着。甚至Firefox也只能正确处理其中一种情况(img,但不是background)。请参考http://softov.org/oria/image-orientation/index.html。 - Csaba Toth

12

自Chrome 81版本以来,默认情况下尊重图像EXIF方向。 最新的Safari(截至目前为止的13.1版本)也正常工作。

Firefox尚未完全实现此功能(请参见Bugzilla问题#1616169)。

这是我发现的几个测试页面:


关于标准,最新的CSS Images Level 3规范草案中,image-orientation属性已被标记为弃用:

'image-orientation'
该属性已被弃用,并且对于实现来说是可选的。


7
我在想Chromium的开发人员是在抽什么东西?他们怎么可能默认启用这样的功能。我们的网站突然出现了各种问题,图片都被旋转到了不同的位置。 - Johncl

10

自最新版本81的chromium/chrome更新开始,它将支持从图片本身读取exif方向。这意味着当图像中存在exif方向信息时,将使用该信息来定位图像,除非出现“image-orientation:none”CSS属性。

在此更新之前,您可能需要使用其他方法旋转图像或根据已知的图像方向手动旋转。然后新的chrome 81将自动旋转图像。如果您需要避免自动旋转并继续使用旧版chrome的同一解决方法,您可能需要设置image-orientation: none,因为现在默认的image-orientation值是from-image

image-orientation支持chrome 81


5

我写了一个小的PHP脚本来旋转图片。 确保将图像存储好,而不只是在每个请求中重新计算它。

<?php

header("Content-type: image/jpeg");
$img = 'IMG URL';

$exif = @exif_read_data($img,0,true);
$orientation = @$exif['IFD0']['Orientation'];
if($orientation == 7 || $orientation == 8) {
    $degrees = 90;
} elseif($orientation == 5 || $orientation == 6) {
    $degrees = 270;
} elseif($orientation == 3 || $orientation == 4) {
    $degrees = 180;
} else {
    $degrees = 0;
}
$rotate = imagerotate(imagecreatefromjpeg($img), $degrees, 0);
imagejpeg($rotate);
imagedestroy($rotate);

?>

干杯


你从哪里得到了方向7、8、5、6、3、4的数字值? - Čamo

2

正如之前的发帖者所说,你需要旋转图像本身。除此之外,你可能还想在EXIF中设置/重置旋转标签。这样,您将避免那些尊重方向标签的查看器再次旋转它。可以为您编辑EXIF的工具称为ExifTool,而且是免费的。


1

0
工具exifautotran可以在事先使用,快速将EXIF方向更改为默认方向(1,“左上角”),并自动旋转图像,使图像看起来与转换之前相同。然后,您可以在网页中使用这些获得的JPG文件,而不必担心这些问题:
a@b:~/a/b/100_PANA$ exifautotran *.JPG
Executing: jpegtran -copy all -rotate 90 P1000638.JPG
Executing: jpegtran -copy all -rotate 270 P1000641.JPG
Executing: jpegtran -copy all -rotate 90 P1000642.JPG
Executing: jpegtran -copy all -rotate 90 P1000645.JPG
…

请注意,仅使用jpegtran -copy all […]命令会保留之前的方向,这可能会导致在某些查看器中图像旋转两次。exifautotran会自动清理这个问题。

1
另一个CLI解决方案:ImageMagick magick mogrify -auto-orient imagefile.jpg - masterxilo
主要问题:jpegtran -copy all -rotate 90 会保留之前的方向,因此如果您的查看器支持exif方向元数据,则图像将旋转两次。解决方法是将方向重置为正常:exiftool -n -Orientation=1 P1000638.JPG - glen
@glen 很好知道。不过,问题是关于网络浏览器的,因此特定图像查看器的花招似乎并不那么相关。只要它是可编写脚本的并且能够产生良好的结果,那么运行一个或两个额外的命令对我来说是可以接受的。不过,老实说,我甚至不记得我是如何使用它以及在哪里使用它的,也不知道是否还保留着它,哈哈。 - Alice M.
exifautotran 是可以的,因为它也调用了 jpegexiforient -1
  • https://github.com/freedesktop-unofficial-mirror/libjpeg/blob/b4f886fcbb692e20fb4da4e6e3ead57f79444734/extra/exifautotran#L47
但是 jpegtran 单独使用不行,因为我指出的问题。
- glen
@glen 刚刚完成了。=) - Alice M.
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接