画像圧縮の原理
- ネイティブ入力タグを介してアップロードする画像ファイルを取得します
- 画像ファイルをimg要素タグに変換
- HTMLImageElementを圧縮してキャンバス上に描画します
- 画像を画像表示を含むデータ URI に変換します。つまり、画像は Base64 でエンコードされた文字列に変換されます。
達成
ネイティブ入力タグを介して、アップロードされた画像ファイルを取得します
- CSS部分
<input ref="image" type="file" accept="image/*" @change="getFile" />
- 画像がアップロードされた後、アップロードされた画像ファイルは次のコードを通じて取得できます。以下の図に示すように、ここには FileList ファイル オブジェクトの配列があります。ここでは単一のファイルをアップロードしているため、配列内の最初のファイル オブジェクトがアップロードした画像ファイルとして直接取得されます。
this.$refs.image.files[0]
画像ファイルをimg要素タグに変換
-
入力で取得したファイルはファイルオブジェクト型のため、圧縮前にimgオブジェクトに変換する必要があり、以下の方法が利用できます。
fileToImg (file) { return new Promise((resolve, reject) => { const img = new Image() const reader = new FileReader() reader.onload = function (e) { img.src = e.target.result } reader.onerror = function (e) { reject(e) } reader.readAsDataURL(file) img.onload = function () { resolve(img) } img.onerror = function (e) { reject(e) } }) }
HTMLImageElement を圧縮してキャンバス上に描画し、画像を Base64 でエンコードされた文字列に変換します。
-
画像を img オブジェクトに変換した後、canvas オブジェクトを作成し、canvas 上に適切な幅と高さの画像を圧縮して描画できます。ここには 2 つのケースがあります。
- 画像を指定した高さに圧縮します
/** * 压缩图片 * @param img 被压缩的img对象 * @param height 触发压缩的图片固定高度 */ compressImgHeight (img, height) { return new Promise((resolve) => { // 创建canvas对象 const canvas = document.createElement('canvas') const context = canvas.getContext('2d') // 获取上传的img图片对象的宽度和高度 const { width: originWidth, height: originHeight } = img // 绘制图片的高度 canvas.height = height // 根据绘制图片的高度,等比例计算图片的宽度 canvas.width = (originWidth * canvas.height) / originHeight // 将img绘制到画布上 context.drawImage(img, 0, 0, canvas.width, canvas.height) // 转为一个包含图片展示的data URI,即图片被转换成base64编码的字符串,格式为jpeg // 0.8为图片质量,区间为0~1,默认0.92 resolve(canvas.toDataURL('image/jpeg', 0.8)) }) },
- 画像を指定した幅に圧縮します
/** * 压缩图片 * @param img 被压缩的img对象 * @param width 触发压缩的图片固定宽度 */ compressImgHeight (img, width) { return new Promise((resolve) => { // 创建canvas对象 const canvas = document.createElement('canvas') const context = canvas.getContext('2d') // 获取上传的img图片对象的宽度和高度 const { width: originWidth, height: originHeight } = img // 绘制图片的宽度 canvas.width = width // 根据绘制图片的宽度,等比例计算图片的高度 canvas.height = (originHeight * canvas.width) / originWidth // 将img绘制到画布上 context.drawImage(img, 0, 0, canvas.width, canvas.height) // 转为一个包含图片展示的data URI,即图片被转换成base64编码的字符串,格式为jpeg // 0.8为图片质量,区间为0~1,默认0.92 resolve(canvas.toDataURL('image/jpeg', 0.8)) }) }
要約する
- 上記のコードを要約すると、
// css部分 <input ref="image" type="file" accept="image/*" @change="getFile" /> // js部分 getFile () { this.readImg(this.$refs.image.files[0]).then(res => { // 压缩图片为指定宽度 this.compressImgHeight(res, 300).then(img => { // 输出压缩后的图片base64 console.log(img) }) }) } /** * 将图片file对象转化为img对象 * @param file 图片file对象 */ fileToImg (file) { return new Promise((resolve, reject) => { const img = new Image() const reader = new FileReader() reader.onload = function (e) { img.src = e.target.result } reader.onerror = function (e) { reject(e) } reader.readAsDataURL(file) img.onload = function () { resolve(img) } img.onerror = function (e) { reject(e) } }) }, /** * 压缩图片为指定宽度 * @param img 被压缩的img对象 * @param width 触发压缩的图片固定宽度 */ compressImgWidth (img, width) { return new Promise((resolve) => { // 创建canvas对象 const canvas = document.createElement('canvas') const context = canvas.getContext('2d') // 获取上传的img图片对象的宽度和高度 const { width: originWidth, height: originHeight } = img // 绘制图片的宽度 canvas.width = width // 根据绘制图片的宽度,等比例计算图片的高度 canvas.height = (originHeight * canvas.width) / originWidth // 将img绘制到画布上 context.drawImage(img, 0, 0, canvas.width, canvas.height) // 转为一个包含图片展示的data URI,即图片被转换成base64编码的字符串,格式为jpeg // 0.8为图片质量,区间为0~1,默认0.92 resolve(canvas.toDataURL('image/jpeg', 0.8)) }) }, /** * 压缩图片为指定高度 * @param img 被压缩的img对象 * @param height 触发压缩的图片固定高度 */ compressImgHeight (img, height) { return new Promise((resolve) => { // 创建canvas对象 const canvas = document.createElement('canvas') const context = canvas.getContext('2d') // 获取上传的img图片对象的宽度和高度 const { width: originWidth, height: originHeight } = img // 绘制图片的高度 canvas.height = height // 根据绘制图片的高度,等比例计算图片的宽度 canvas.width = (originWidth * canvas.height) / originHeight // 将img绘制到画布上 context.drawImage(img, 0, 0, canvas.width, canvas.height) // 转为一个包含图片展示的data URI,即图片被转换成base64编码的字符串,格式为jpeg // 0.8为图片质量,区间为0~1,默认0.92 resolve(canvas.toDataURL('image/jpeg', 0.8)) }) }