ホームページ  >  に質問  >  本文

javascript - JS获取iphone图库中图片的宽高异常

我想要在上传图片前先让用户预览图片,我想要得到图片的宽度和高度进行resize,我的代码如下:

var pic = new Image();
var pw,ph;
pic.onload = function(){
    pw = pic.width;
    ph = pic.height;    
    console.log(pw,ph);
    // other code...                    
}
pic.src = url;

我在桌面端的很多浏览器都测过,都挺正常的。后来开始测移动端,在iphone上时而出问题时而正常。反复测试后发现问题出在使用iphone摄像头拍摄的照片,这些照片尺寸是3264x2448,但是其实照片的尺寸是2448x3264,宽和高正好是相反的,后来我把照片导到电脑里,的确尺寸应该是2448x3264。我不知道这种情况是怎么导致的~~~~~

巴扎黑巴扎黑2749日前418

全員に返信(4)返信します

  • 黄舟

    黄舟2017-04-10 14:29:42

    悄悄告诉你,做这个功能会坑死你。

    目前我用了约 30k 的代码来实现该功能。具体效果可以看 http://qingpai.baidu.com

    常规解决方案

    1. 使用 FileReader 获取图片信息
    2. 读取图片的 exif 信息,并解析出其中的 orientation 、PixelXDimension,PixelYDimension 信息
    3. 用 canvas 及 canvas 2d 的相关 api 按照 orientation 进行旋转。
    4. 输出 canvas 信息。

    bug list

    1. iOS 对读取图片尺寸有限制(100万像素)。而实际拍照的照片均在 100w 像素以上,会导致直接读取图片是,图片的高度坍塌,需要特殊处理
    2. iOS 对图片进行 canvas 处理时,获取到的图片是原始图片的副本,长宽为原始图片的一半。
    3. 图片太大会导致内存爆掉,处理图片时,页面也会进入假死状态。5s 需要 300ms,iPhone4s 处理时间约 2s
    4. UC 不吃 iOS 这一套,修 iOS bug 1 的方案会导致 UC 浏览器渲染出问题。

    思路就基本这样了

    解决方案网上都有现成的,自己动手搜一搜就能找到。

    https://github.com/QzoneTouch/commonWidget 这个地址包含了一部分解决方案。

    返事
    0
  • PHP中文网

    PHP中文网2017-04-10 14:29:42

    iPhone拍摄的图片的起始点是屏幕的左下角,所以宽和高是相反的。。

    返事
    0
  • PHP中文网

    PHP中文网2017-04-10 14:29:42

    你拍照时,iPhone 会根据重力感应决定你的照片的宽和高,举个例子,你如果横着拍照,得到的照片的宽高比是4:3,如果是竖着拍照的话宽高比就成了3:4了,你可以测试一下看看。

    返事
    0
  • 怪我咯

    怪我咯2017-04-10 14:29:42

    前端:

    https://github.com/gokercebeci/canvasResize

    在后端也是一样转嘛(php):

    $exif = exif_read_data($picAddr);
    $image = imagecreatefromjpeg($picAddr);
    if($exif['Orientation'] == 3) {
        $result = imagerotate($image, 180, 0);
        imagejpeg($result, $picAddr, 100);
    } elseif($exif['Orientation'] == 6) {
        $result = imagerotate($image, -90, 0);
        imagejpeg($result, $picAddr, 100);
    } elseif($exif['Orientation'] == 8) {
        $result = imagerotate($image, 90, 0);
        imagejpeg($result, $picAddr, 100);
    }
    isset($result) && imagedestroy($result);
    imagedestroy($image);

    返事
    0
  • キャンセル返事