如何调整图像的方向以显示正确的图像预览?

Posted

技术标签:

【中文标题】如何调整图像的方向以显示正确的图像预览?【英文标题】:How to adjust the orientation of a image in order to show proper preview of the image? 【发布时间】:2020-04-17 02:59:56 【问题描述】:

我开发了一个laravel web应用程序,它具有接受用户上传的图片然后显示的功能。我在测试时遇到了一个问题,因为使用手机上传的照片在逆时针方向旋转了 90 度,我使用图像干预来解决这个问题。但是当我使用javascript向用户显示上传图像的预览时,图像旋转了90度,但是当我保存图像时它变得正确。 我的 javascript 代码是

    function imagePreview(input,elm) 
        if (input.files && input.files[0]) 
            var reader = new FileReader();
            reader.onload = function (e) 
                $(elm).css("background-image","url('"+e.target.result+"')");
            
            reader.readAsDataURL(input.files[0]);
        
    
    $("#settings_img").on("change",function()
        imagePreview(this,"#settings_img_elm");
    );

任何人都可以通过编辑上面的代码来帮助我正确定位预览图像,以便在需要时改变图像的方向。

【问题讨论】:

这能回答你的问题吗? JS Client-Side Exif Orientation: Rotate and Mirror JPEG Images 我尝试了这些代码,但我无法获得正确的输出我是 Web 开发的新手,因此我希望有人为我编辑我的代码@Nick 【参考方案1】:

用 CSS 旋转图像怎么样?

reader.onload = function (e) 
    $(elm).css(
        "background-image":"url('"+e.target.result+"')",
        "transform": "rotate(90deg)"
    );


编辑:好吧,在简要了解一下 EXIF 数据的世界之后,我想我可能会为您提供一个解决方案。正如@Nick 建议的那样,我借用了 Ali 的 getOrientation() 函数,然后我只是用 CSS 更正了方向,如下所示:

function correctOrientation(element, orientation)
    switch (orientation) 
      case 2: $(element).css("transform", "scaleX(-1)");
        break;
      case 3: $(element).css("transform", "rotate(180deg)");
        break;
      case 4: $(element).css("transform", "rotate(180deg) scaleX(-1)");
        break;
      case 5: $(element).css("transform", "rotate(-90deg) scaleX(-1)");
        break;
      case 6: $(element).css("transform", "rotate(90deg)");
        break;
      case 7: $(element).css("transform", "rotate(90deg) scaleX(-1)");
        break;
      case 8: $(element).css("transform", "rotate(-90deg)");
        break;
      default: break;
    

fiddle

如果您需要示例文件来测试它,get them here。


编辑: 将上传的图片放在<img> 中,而不是 div 的背景图片中: https://jsfiddle.net/ynzvtLe2/2/

【讨论】:

这个问题是有些手机会以正确的方向预览图像,因此 css 旋转会弄乱这些图像@thingEvery 我只想知道如何将其放入我的代码中 @JeffrinJose 是的,兄弟。我这样做了。只需到这里jsfiddle.net/n5sm7ucf/1 并从 javascript 框中复制所有内容。 (用那个替换你的JS代码。)哦,你也需要CSS。不过,如果你真的想要,你可以使用 jQuery 以编程方式添加它,就像你在“imagePreview”函数中所做的那样。 @JeffrinJose 如果你仍然卡住,@我。 非常感谢您的帮助,我实际上是在使用 php 上传和显示文件,只有预览部分是由我在 laravel 上工作的 js 完成的【参考方案2】:

这应该可行。在这里,我得到了图像文件的原始方向,然后用适当的旋转校正构建了一个画布。然后我们将正确旋转的图像设置为预览。

function imagePreview(input,elm) 
    // image file
    var file = input.files[0]; 

    if (!file.type.match('image/jpeg.*')) 
        // image is not a jpeg, do something?
    

    var reader = new FileReader();
    reader.onload = function(e) 
        var exif = piexif.load(e.target.result);
        var image = new Image();
        image.onload = function () 
            //get original orientation of the uploaded image
            var orientation = exif["0th"][piexif.ImageIFD.Orientation];

            // Build a temperory canvas to manipulate image to required orientation
            var canvas = document.createElement("canvas");
            canvas.width = image.width;
            canvas.height = image.height;
            var ctx = canvas.getContext("2d");
            var x = 0;
            var y = 0;
            ctx.save();
            if (orientation == 2) 
                x = -canvas.width;
                ctx.scale(-1, 1);
             else if (orientation == 3) 
                x = -canvas.width;
                y = -canvas.height;
                ctx.scale(-1, -1);
             else if (orientation == 4) 
                y = -canvas.height;
                ctx.scale(1, -1);
             else if (orientation == 5) 
                canvas.width = image.height;
                canvas.height = image.width;
                ctx.translate(canvas.width, canvas.height / canvas.width);
                ctx.rotate(Math.PI / 2);
                y = -canvas.width;
                ctx.scale(1, -1);
             else if (orientation == 6) 
                canvas.width = image.height;
                canvas.height = image.width;
                ctx.translate(canvas.width, canvas.height / canvas.width);
                ctx.rotate(Math.PI / 2);
             else if (orientation == 7) 
                canvas.width = image.height;
                canvas.height = image.width;
                ctx.translate(canvas.width, canvas.height / canvas.width);
                ctx.rotate(Math.PI / 2);
                x = -canvas.height;
                ctx.scale(-1, 1);
             else if (orientation == 8) 
                canvas.width = image.height;
                canvas.height = image.width;
                ctx.translate(canvas.width, canvas.height / canvas.width);
                ctx.rotate(Math.PI / 2);
                x = -canvas.height;
                y = -canvas.width;
                ctx.scale(-1, -1);
            
            ctx.drawImage(image, x, y);
            ctx.restore();

            var dataURL = canvas.toDataURL("image/jpeg", 1.0);

            // set the preview image to your element
            $(elm).css("background-image","url('"+dataURL+"')");
        ;
        image.src = e.target.result;
    ;

    reader.readAsDataURL(file);




$("#settings_img").on("change",function()
    imagePreview(this,"#settings_img_elm");
);

确保首先包含此库: https://github.com/hMatoba/piexifjs

我从文档中得到了帮助: https://readthedocs.org/projects/piexif/downloads/pdf/latest/

【讨论】:

如果我用我的javascript文件中的这段代码代替上面给出的代码,那么一切都会正常工作吗??? @Jeffrin Jose 是的。请尝试一下 我试过了,只是预览图不可见 是否还有其他因素会影响这一点 @JeffrinJose 你是否正确地包含了这个库?

以上是关于如何调整图像的方向以显示正确的图像预览?的主要内容,如果未能解决你的问题,请参考以下文章

Jcrop 图像在预览中无法正确显示

如何在上传前调整图像大小并进行预览

如何以正确的方向旋转图像

有没有一种方法来调整位图图像的大小?

以正确的方向显示图像 - Blazor 服务器端

iOS:自定义相机如何始终以正确的方向保存图像?