>  기사  >  웹 프론트엔드  >  Vue의 입력을 기반으로 이미지 업로드, 압축, 접합 및 회전에 대한 자세한 코드 설명

Vue의 입력을 기반으로 이미지 업로드, 압축, 접합 및 회전에 대한 자세한 코드 설명

不言
不言앞으로
2018-11-26 14:41:452849검색

이 글은 PHP 큐의 구현 코드를 소개합니다. 필요한 친구들이 참고할 수 있기를 바랍니다.

프론트엔드 직원으로서 시스템을 개발할 때 사용자를 위해 업로드된 이미지를 저장해야 하는 경우가 종종 있다고 생각합니다. 이 글을 다 읽고 나면, 사실은 그렇게 간단하다는 것을 알게 될 것입니다.

# 🎜🎜#

이미지 파일 업로드

이제 많은 프로젝트에서 시스템에 이미지 저장을 구현하고 있으며 대부분은 해당 이미지의 URL만 시스템 데이터베이스에 저장하는 반면 실제 이미지 리소스는 이미지에 저장됩니다. 물론 일부 프로젝트에서는 자체 데이터베이스에 문자열을 base64 형식으로 저장하도록 선택합니다. 다음은 이 두 가지 방법의 구체적인 구현을 보여줍니다. #🎜 🎜 #

Vue의 입력을 기반으로 이미지 업로드, 압축, 접합 및 회전에 대한 자세한 코드 설명우선, 사용자로부터 이미지 리소스를 얻어야 합니다. 이때 html의 태그, 유형 값은 파일, 입력 태그를 파일 유형의 양식 입력으로 지정하고 해당 속성을 "image/*"로 설정하여 이미지 리소스 파일만 허용되도록 지정합니다.

<input>
# 🎜🎜#다음으로, 사용자가 선택한 파일을 가져와야 합니다. 사용자가 파일을 선택하면 입력 태그의 변경 이벤트가 트리거되고 이벤트 개체를 가져와 이미지 파일을 가져올 수 있습니다. event:

 <input>
파일을 가져오기 위해 클릭한 후 $event 개체를 통해 이미지 리소스 파일 개체를 가져오고 $event.target.files[0]을 가져올 수 있습니다. 파일 업로드 입력 양식이 다중 속성을 지원하기 때문입니다. 파일을 업로드하려면 입력 태그에 다중 속성만 추가하면 아래 그림에서 파일 객체의 일부 속성을 볼 수 있습니다.

Vue의 입력을 기반으로 이미지 업로드, 압축, 접합 및 회전에 대한 자세한 코드 설명관찰 후 파일 객체에 이미지 크기를 나타내는 크기 속성이 있음을 발견했습니다. 지정된 작업에 대해 파일을 얻었는지 확인하기 위해 이 속성의 값이 비어 있는지 여부

fileChange(el, index) {
    if (!el.target.files[0].size) return;
}
이 시점에서 우리는 원하는 파일 객체를 얻었습니다. 이미지 압축 함수를 지정하고 압축 함수 이름을 지정합니다.

Image 압축

우선, 이미지 리소스를 압축해야 합니다. 첫 번째 단계는 이미지 리소스를 얻는 것입니다.

 compress(event) {
        var file = event.target.files;
        var reader = new FileReader(), imgFile = file[0];
        if (imgFile.type.indexOf('image') == 0) {
          reader.readAsDataURL(imgFile);
        } else {
          this.$Message.infor('文件类型仅为图片')
        }
 }

여기에 있는 일부 사람들은 FileReader 개체를 이해하지 못할 수도 있습니다. FileReader 개체를 사용하면 웹 응용 프로그램이 사용자 컴퓨터에 저장된 파일(또는 원시 데이터 버퍼)의 내용을 비동기적으로 읽을 수 있습니다. File 또는 Blob 개체를 사용하여 읽을 파일이나 데이터를 지정합니다. 여기서는 읽기가 완료되었는지 확인하기 위해 주로 온로드를 모니터링하는 데 사용되며, 읽기가 완료되면 새로 생성된 Image 개체에 읽기 결과를 할당합니다. 후속 압축을 위한 객체입니다. 이때 읽은 결과는 실제로 base64 형식입니다. 문자열

(매우 길다는 뜻입니다.

# 🎜🎜#

이 때 여기에 base64 문자열이 나타나는 것을 볼 수 있습니다. Vue의 입력을 기반으로 이미지 업로드, 압축, 접합 및 회전에 대한 자세한 코드 설명

Vue의 입력을 기반으로 이미지 업로드, 압축, 접합 및 회전에 대한 자세한 코드 설명

整个函数实现如下:

compress(event) {
        var file = event.target.files;
        var reader = new FileReader(), imgFile = file[0];
        if (imgFile.type.indexOf('image') == 0) {
          reader.readAsDataURL(imgFile);
        } else {
          this.$Message.infor('文件类型仅为图片')
        }
        let img = new Image();
        reader.onload = function (e) {
          img.src = e.target.result;
        };
        var imgP = new Promise((resolve, reject) => {
          img.onload = () => {
            var canvas = document.createElement("canvas");
            var ctx = canvas.getContext('2d');
            //    瓦片canvas
            var tCanvas = document.createElement("canvas");
            var tctx = tCanvas.getContext("2d");
            var initSize = img.src.length;
            var width = img.width;
            var height = img.height;
            //图片像素大于400万像素,计算压缩到400万以下
            var ratio;
            if ((ratio = width * height / 4000000) > 1) {
              ratio = Math.sqrt(ratio);
              width /= ratio;
              height /= ratio;
            } else {
              ratio = 1;
            }
            canvas.width = width;
            canvas.height = height;
            ctx.fillStyle = "#fff";
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            //如果图片太大则使用瓦片绘制
            var count;
            if ((count = width * height / 1000000 > 1)) {
              count = ~~(Math.sqrt(count) + 1);//计算分成的瓦片数
              var nw = ~~(width / count);
              var nh = ~~(height / count);
              tCanvas.width = nw;
              tCanvas.height = nh;
              for (var i = 0; i <h2>图片拼接</h2><p>需要注意的一点了,上面压缩的过程使用了瓦片绘制,可能会导致拼接过程中不紧凑而产生一条间隙,这个只需要调整一下绘制瓦片的坐标位置即可,该思想同样可以用于处理图片拼接的问题,可按照上面思路进行拼接,这里就不再举例子说明了,瓦片绘制就是图片拼接的过程;</p><h2>图片旋转</h2><p>压缩和拼接都讲完啦,在对图片进行处理,大家都有自己的见解了,或许你们还会这么说,那如果我上传图片的时候,像把那些横着排的照片,也放成竖起来,要怎么处理,竟调整图片放置的方向,该怎么处理,这就需要用到canvas的rotate方法去实现了,老方法,我们先获取图片对象,因为之前的压缩是放回一个promise对象,data参数为img的base64格式,所以我们把旋转函数的参数定义为图片来源;</p><pre class="brush:php;toolbar:false">rotate(imgData) {
        var img = new Image();
        img.src = imgData;
        var imgR = new Promise((resolve, reject) => {
         img.onload = ()=>{
            console.log(img.width)
             console.log(img.naturalWidth)
          }
        })
      },

这里需要注意的是,每次我们新建一个image对象,想要获取其一些响应的属性值,一定要在onload方法中,确保图片已经加载完毕,上面的console中输出了两个值,width和naturalWidth,在某中条件下,他们会是相等的,比如我们上面,也会存在不一致的时候,因为naturalWidth返回的依然是图片的真实尺寸,而width返回的是给img标签规定的尺寸,所以我们需要获取的是naturalWidth;

rotate(imgData) {
        var img = new Image();
        img.src = imgData;
        var imgR = new Promise((resolve, reject) => {
          img.onload = () => {
            let degree = 0, drawHeight, drawWidth;
            drawHeight = img.naturalHeight;
            drawWidth = img.naturalWidth;
            let maxSide = Math.max(drawWidth, drawHeight);
            if (maxSide === drawWidth) {//判断需要旋转的角度
              degree = 90;
            } else {
              degree = 360;
            }
            var canvas = document.createElement('canvas');
            canvas.width = drawWidth;
            canvas.height = drawHeight;
            var context = canvas.getContext('2d');
            context.translate(drawWidth/2,drawHeight/2)//这一行和下下一行的作用是修改选择中心
            context.rotate(degree*Math.PI/180);//旋转图片
            context.translate(-drawWidth/2,-drawHeight/2)//这一行和上上一行的作用是修改选择中心
            context.drawImage(img, 0, 0, drawWidth, drawHeight);
            var ndata = canvas.toDataURL('image/jpeg', 1);
            context.width = context.height = 0;
            resolve(ndata)

          }
        })

        return Promise.all([imgR])
      }

旋转效果如下,宽大于高的,即是横排的图片,就会发生旋转;

Vue의 입력을 기반으로 이미지 업로드, 압축, 접합 및 회전에 대한 자세한 코드 설명

总结

在vue下利用canvas实现上述功能后,发现了canvas在图片处理这块的强大功能,对于前端上传图片性能的优化会有很大的帮助;经过上述的时间,发现要实现用户的上传图片前的裁剪功能,以及可以利用canvas来实现,主要是利用drawImage控制裁剪的长度,起点坐标就可以实现,着实好用!

위 내용은 Vue의 입력을 기반으로 이미지 업로드, 압축, 접합 및 회전에 대한 자세한 코드 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제