在移动网络浏览器中使用 input[type='file'] 捕获照片后,如何在画布中以正确的方向绘制照片? [英] How to draw photo with correct orientation in canvas after capture photo by using input[type='file'] in mobile web browser?

查看:18
本文介绍了在移动网络浏览器中使用 input[type='file'] 捕获照片后,如何在画布中以正确的方向绘制照片?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在移动端制作一个简单的网络应用程序,它允许访问者使用 html5 input[type=file] 元素捕捉照片.然后我将它显示在网络上进行预览,然后访问者可以选择将照片上传到我的服务器用于其他目的(即:上传到FB)

当我使用 iPhone 拍照并垂直握住照片时,我发现照片的方向有问题.照片在标签中的方向正确.但是,当我尝试使用 drawImage() 方法将其绘制到画布中时,它被绘制了 90 度旋转.

我尝试了 4 个方向的照片,其中只有一个可以在画布上绘制正确的图像,其他方向旋转甚至倒置.

好吧,我很困惑获得正确的方向来解决这个问题......感谢您的帮助...

这是我的代码,大部分是从 MDN 复制的

<h1>相机API</h1><section class="main-content"><p>Camera API 的演示,目前在 Android 上的 Firefox 和 Google Chrome 中实现.选择使用设备的相机拍照,预览将通过 createObjectURL 或 FileReader 对象显示(选择也支持本地文件).</p><p><form method="post" enctype="multipart/form-data" action="index.php"><input type="file" id="take-picture" name="image" accept="image/*"><input type="hidden" name="action" value="submit"><输入类型=提交"></表单></p><h2>预览:</h2><div style="width:100%;max-width:320px;"><img src="about:blank" alt="" id="show-picture" width="100%">

<p id="错误"></p><canvas id="c" width="640" height="480"></canvas></节>

<脚本>(功能 () {var takePicture = document.querySelector("#take-picture"),showPicture = document.querySelector("#show-picture");if (takePicture && showPicture) {//设置事件takePicture.onchange = 函数(事件){showPicture.onload = 函数(){var canvas = document.querySelector("#c");var ctx = canvas.getContext("2d");ctx.drawImage(showPicture,0,0,showPicture.width,showPicture.height);}//获取对拍摄的图片或所选文件的引用var 文件 = event.target.files,文件;如果(文件&&文件.长度> 0){文件 = 文件 [0];尝试 {//获取 window.URL 对象var URL = window.URL ||window.webkitURL;//创建对象URLvar imgURL = URL.createObjectURL(file);//设置 img src 为 ObjectURLshowPicture.src = imgURL;//撤销 ObjectURLURL.revokeObjectURL(imgURL);}抓住 (e) {尝试 {//如果不支持 createObjectURL 则回退var fileReader = new FileReader();fileReader.onload = 函数(事件){showPicture.src = event.target.result;};fileReader.readAsDataURL(文件);}抓住 (e) {//显示错误信息var error = document.querySelector("#error");如果(错误){error.innerHTML = "不支持 createObjectURL 或 FileReader";}}}}};}})();

解决方案

您需要读取 exif 数据并检查 exif.Orientation 是否为以下之一:

fileReader.onloadend = function() {var exif = EXIF.readFromBinaryFile(new BinaryFile(this.result));开关(exif.Orientation){案例8:ctx.rotate(90*Math.PI/180);休息;案例3:ctx.rotate(180*Math.PI/180);休息;案例6:ctx.rotate(-90*Math.PI/180);休息;}};

I am making a simple web app in mobile which allow visitor to capture photo by using html5 input[type=file] element. Then I will display it on the web for preview, and then visitor can choose to upload the photo to my server for other purpose(ie: upload to FB)

I find a problem on the orientation of photo when I take photo using my iPhone and hold vertically.The photo is in a correct orientation in tag. However, when I try to draw it into canvas by using drawImage() method, it is drawn 90 degree rotated.

I have tried to take photo in 4 orientations, only one of them can draw a correct image in canvas, others are rotated or even flipped upside down.

Well, I am confused to get the correct orientation to fix this problem... Thanks for helping...

here is my code, mostly copy from MDN

<div class="container">
            <h1>Camera API</h1>

            <section class="main-content">
                <p>A demo of the Camera API, currently implemented in Firefox and Google Chrome on Android. Choose to take a picture with your device's camera and a preview will be shown through createObjectURL or a FileReader object (choosing local files supported too).</p>

                <p>
                    <form method="post" enctype="multipart/form-data" action="index.php">
                        <input type="file" id="take-picture" name="image" accept="image/*">
                        <input type="hidden" name="action" value="submit">
                        <input type="submit" >
                    </form>
                </p>

                <h2>Preview:</h2>
                <div style="width:100%;max-width:320px;">
                    <img src="about:blank" alt="" id="show-picture" width="100%">
                </div>

                <p id="error"></p>
                <canvas id="c" width="640" height="480"></canvas>
            </section>

        </div>


        <script>
            (function () {
                var takePicture = document.querySelector("#take-picture"),
                    showPicture = document.querySelector("#show-picture");

                if (takePicture && showPicture) {
                    // Set events
                    takePicture.onchange = function (event) {
                        showPicture.onload = function(){
                            var canvas = document.querySelector("#c");
                            var ctx = canvas.getContext("2d");
                            ctx.drawImage(showPicture,0,0,showPicture.width,showPicture.height);
                        }
                        // Get a reference to the taken picture or chosen file
                        var files = event.target.files,
                            file;
                        if (files && files.length > 0) {
                            file = files[0];
                            try {
                                // Get window.URL object
                                var URL = window.URL || window.webkitURL;

                                // Create ObjectURL
                                var imgURL = URL.createObjectURL(file);

                                // Set img src to ObjectURL
                                showPicture.src = imgURL;

                                // Revoke ObjectURL
                                URL.revokeObjectURL(imgURL);
                            }
                            catch (e) {
                                try {
                                    // Fallback if createObjectURL is not supported
                                    var fileReader = new FileReader();
                                    fileReader.onload = function (event) {
                                        showPicture.src = event.target.result;

                                    };
                                    fileReader.readAsDataURL(file);
                                }
                                catch (e) {
                                    // Display error message
                                    var error = document.querySelector("#error");
                                    if (error) {
                                        error.innerHTML = "Neither createObjectURL or FileReader are supported";
                                    }
                                }
                            }
                        }
                    };
                }
            })();
        </script>

解决方案

You'll need to read the exif data and check if exif.Orientation is one of the following:

fileReader.onloadend = function() {

    var exif = EXIF.readFromBinaryFile(new BinaryFile(this.result));

    switch(exif.Orientation){

       case 8:
           ctx.rotate(90*Math.PI/180);
           break;
       case 3:
           ctx.rotate(180*Math.PI/180);
           break;
       case 6:
           ctx.rotate(-90*Math.PI/180);
           break;


    }
};

这篇关于在移动网络浏览器中使用 input[type='file'] 捕获照片后,如何在画布中以正确的方向绘制照片?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆