ホームページ > 記事 > ウェブフロントエンド > vue での入力に基づく画像のアップロード、圧縮、結合、回転の詳細なコード説明
この記事では、PHP キューの実装コードについて説明します。必要な方は参考にしていただければ幸いです。
フロントエンドスタッフとして、システムを開発する際に、アップロードした画像をユーザーのために保存する必要があることがよくあると思います。多くの初心者がこの問題に遭遇すると、誰もがショックを受け、難しいことだと思います。この記事を読み終えると、実際は、これをやみくもに行っていることがわかります。
画像ファイルのアップロード## です。 ##現在、多くのプロジェクトはシステムに画像を保存していますが、そのほとんどは対応する画像の URL をシステム データベースに保存するだけですが、実際の画像リソースは Alibaba などの画像サーバーに配置されます。画像文字列を独自のデータベースに Base64 形式で保存することを選択したプロジェクト。これら 2 つのメソッドの具体的な実装を、vue インスタンスで示します。
まず、ユーザーから画像リソースを取得する必要があります。このとき、html の <input> タグを使用する必要があります。type の値は file で、input タグはファイルの種類として指定されます。フォーム入力を行い、その accept 属性を「image/*」に設定して、画像リソース ファイルのみを受け入れるように指定します。次に、ユーザーが選択したファイルを取得します。 file を指定すると、input タグの変更イベントがトリガーされます。イベントをリッスンしてイベント オブジェクトを取得することで、画像ファイルを取得できます。
<input>
をクリックしてファイルを取得した後、$ を取得できます。 $event object.event.target.files[0] で画像リソースファイルオブジェクトを取得するため、ファイルアップロード入力フォームが複数のファイルアップロードをサポートしているためです。 input タグを参照して、画像ファイル オブジェクトのいくつかの属性を確認します。
観察した結果、サイズがあることがわかりました。ファイル オブジェクト内の画像のサイズを示す属性を使用して、指定された操作のためにファイルが取得されたかどうかを確認できます。この時点で、必要なファイル オブジェクトを取得しました。次に、画像圧縮関数を実装し、名前を付けます。圧縮関数の場合: Image Compression
まず、圧縮する必要があります。最初のステップは、画像リソースを取得し、それを確認することです。
<input>
FileReader オブジェクトを使用すると、Web アプリケーションはファイルの内容を非同期的に読み取ることができます。ユーザーのコンピューターに保存されているファイル (または生データ バッファー) を使用して、読み取られるファイルまたはデータを指定します。ここでは主に、読み取りがいつ完了したかを判断するために onload を監視します。読み取りが完了すると、読み取り結果を後続の圧縮のオブジェクトとして新しく作成した Image オブジェクトに割り当てます。読み取った結果が実際には Base64 形式の文字列であることがわかります
(非常に長い)。 ..、これは単なるつもりです)
この時点で、base64 文字列がここに表示されていることがわかります。これは値としてコピーできます。 タグの src 属性に追加することで画像をレンダリングすることもできますが、この形式で画像を保存することを選択する人もいます。データベースが冗長すぎます;
fileChange(el, index) { if (!el.target.files[0].size) return; }
画像を圧縮するには、主に Canvas.getContext(' 2d').drawImage() メソッドを通じて画像を再描画し、canvas を使用してこの機能を実現します。 toDataURL(type, encoderOptions) メソッドは、画像表示を含む dataURI を返します。type は画像の形式、encoderOptions は画像の明瞭度、0 から 1 まで増加します。この圧縮プロセスを理解するのは難しくありません。画像の高さと幅を取得し、そのピクセル サイズを計算し、それを自分で設定した制限値と比較して、サイズを圧縮する必要があるかどうかを確認します。たとえば、例の比率は画像の幅と高さを表します。圧縮率。幅と高さを変更せずに画像のファイル サイズを変更し、drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) を介して画像を再描画できます。 9 つのパラメータはそれぞれ、コンテキストに描画される要素、ソース画像の長方形の選択ボックスの左上隅の X 座標、ソース画像の長方形の選択ボックスの左上隅の Y 座標、幅を表します。ソース画像の長方形の選択ボックスの高さと、ターゲット キャンバスの左上隅がターゲット キャンバスの X 軸の位置にあり、ソース画像の長方形の選択ボックスが上になります。ターゲット キャンバスの左隅は、ターゲット キャンバス上の Y 軸の位置、ターゲット キャンバスに描画される画像の幅、およびターゲット キャンバスに描画される画像の高さになります。
整个函数实现如下:
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下利用canvas实现上述功能后,发现了canvas在图片处理这块的强大功能,对于前端上传图片性能的优化会有很大的帮助;经过上述的时间,发现要实现用户的上传图片前的裁剪功能,以及可以利用canvas来实现,主要是利用drawImage控制裁剪的长度,起点坐标就可以实现,着实好用!
以上がvue での入力に基づく画像のアップロード、圧縮、結合、回転の詳細なコード説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。