사진 압축 원리
- 기본 입력 태그를 통해 업로드할 이미지 파일 가져오기
- 이미지 파일을 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 객체로 변환한 후 캔버스 객체를 생성하고 캔버스에 적당한 너비와 높이로 그림을 압축하여 그릴 수 있습니다. 여기에는 두 가지 경우가 있습니다.
- 이미지를 지정된 높이로 압축
/** * 压缩图片 * @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)) }) }