IONIC -电容器/摄像头-更改图像大小或压缩图像

92dk7w1h  于 2023-09-28  发布在  Ionic
关注(0)|答案(1)|浏览(150)

我使用@capacitor/camera库拍摄了一张照片,使用了以下代码:

let capturedPhoto:any = await Camera
    .getPhoto({
      resultType: CameraResultType.Uri,
      source: CameraSource.Camera,
      quality: 30,
      height: 150,
      allowEditing: false,
      direction: CameraDirection.Front
    })
    .catch(err => {

    });

当我在Android或iOS中使用此代码的应用程序时,图片文件太大(接近4 MB)。这个文件需要存储在Firebase存储中,我需要保存空间,因为在大量用户的成本可以由一个问题。
所以一个不知道我该怎么做来调整图片大小或压缩图像?我需要一些算法在typescript实现没有画布或HTML的使用。这可能吗
我的想法是使用“capturedPhoto”并以某种方式处理它,但我可以找到的所有选项都使用画布或HTML元素,并且不起作用,或者我不知道如何实现。
capturePhoto有这种格式,当一个尝试把jpg,“选项”为Camera.getPhoto,不要让我。

{
    "webPath": "blob:http://localhost:8100/df29b43e-da65-4345-8bbb-704a8745d483",
    "format": "png",
    "saved": false
}
brqmpdu1

brqmpdu11#

最后,我终于可以解决我的问题了。
我可以找到并合并不同平台和语言的各种解决方案,以生成我自己的调整图片大小的函数(使用画布,是的,但不与HTML页面交互)。
第一个测试是去非常好,用电脑相机拍摄的照片有它285KB,结果结束了2.75KB(在一个极端的大小减少),在加上转换的png到jpg.
我将介绍next函数(resizeImage),但它与我在项目中需要使用的所有其他函数集成在一个服务中。

import { Injectable } from '@angular/core';
// NATIVE CAMERA
import { Camera, CameraDirection, CameraResultType, CameraSource, Photo } from '@capacitor/camera';
import {decode} from "base64-arraybuffer";
// https://ionicframework.com/docs/native/camera
// https://www.npmjs.com/package/@capacitor/camera

import * as moment from 'moment'

@Injectable({
  providedIn: 'root'
})
export class PhotoService {
  base64ResizedImage: string = null;
  constructor(
  ) { }

  async takePicture() {
    return await Camera
      .getPhoto({
        resultType: CameraResultType.Uri,
        source: CameraSource.Camera,
        quality: 30,
        height: 150,
        allowEditing: false,
        direction: CameraDirection.Front
      })
      .catch(err => {
        return undefined;
      });
  }

  base64StringToFile(base64String: string, format: string) {
    const blob = new Blob([new Uint8Array(decode(base64String))], {
      type: `image/${format}`,
    });
    let file:any = new File([blob], "Name", {
      lastModified: moment().unix(),
      type: blob.type,
    });

    return file;
  }

  base64Tobase64String(base64: string) {
    console.log("photo.service.ts: base64Tobase64String => base64", base64);
    let result = base64.split(';base64,')[1];
    console.log("photo.service.ts: base64Tobase64String => base64String", result);
    return result;
  }

  getTypeBase64(base64: string) {
    let type = base64.substring("data:image/".length, base64.indexOf(";base64"));
    console.log("photo.service.ts: getTypeBase64 => type", type);
    return type;
  }

  resizeImage(base64image: string, width: number, height: number) {
    return new Promise((resolve, reject) => {
      console.log("photo.service.ts: resizeImage => entered");
      let img = new Image();
      img.src = base64image;

      var that = this;
      img.onload = function () {
        console.log("photo.service.ts: resizeImage => img.onload");

        // Check if the image require resize at all
        if(img.height <= height && img.width <= width) {
          that.base64ResizedImage = base64image;

          // TODO: Call method to do something with the resize image
          console.log("photo.service.ts: resizeImage => not require resize");
          resolve (that.base64ResizedImage);
        }
        else {
          // Make sure the width and height preserve the original aspect ratio and adjust if needed
          if(img.height > img.width) {
            width = Math.floor(height * (img.width / img.height));
          }
          else {
            height = Math.floor(width * (img.height / img.width));
          }

          let resizingCanvas: HTMLCanvasElement = document.createElement('canvas');
          let resizingCanvasContext = resizingCanvas.getContext("2d");

          // Start with original image size
          resizingCanvas.width = img.width;
          resizingCanvas.height = img.height;

          // Draw the original image on the (temp) resizing canvas
          resizingCanvasContext.drawImage(img, 0, 0, resizingCanvas.width, resizingCanvas.height);

          let curImageDimensions = {
            width: Math.floor(img.width),
            height: Math.floor(img.height)
          };

          let halfImageDimensions = {
            width: 0,
            height: 0
          };

          // Quickly reduce the dize by 50% each time in few iterations until the size is less then
          // 2x time the target size - the motivation for it, is to reduce the aliasing that would have been
          // created with direct reduction of very big image to small image
          while (curImageDimensions.width * 0.5 > width) {
            // Reduce the resizing canvas by half and refresh the image
            halfImageDimensions.width = Math.floor(curImageDimensions.width * 0.5);
            halfImageDimensions.height = Math.floor(curImageDimensions.height * 0.5);

            resizingCanvasContext.drawImage(resizingCanvas, 0, 0, curImageDimensions.width, curImageDimensions.height, 0, 0, halfImageDimensions.width, halfImageDimensions.height);

            curImageDimensions.width = halfImageDimensions.width;
            curImageDimensions.height = halfImageDimensions.height;
          }

          // Now do final resize for the resizingCanvas to meet the dimension requirments
          // directly to the output canvas, that will output the final image
          let outputCanvas: HTMLCanvasElement = document.createElement('canvas');
          let outputCanvasContext = outputCanvas.getContext("2d");

          outputCanvas.width = width;
          outputCanvas.height = height;

          outputCanvasContext.drawImage(resizingCanvas, 0, 0, curImageDimensions.width, curImageDimensions.height, 0, 0, width, height);

          // output the canvas pixels as an image. params: format, quality
          that.base64ResizedImage = outputCanvas.toDataURL('image/jpeg', 0.85);

          // TODO: Call method to do something with the resize image
          console.log("photo.service.ts: resizeImage => resize OK");
          resolve (that.base64ResizedImage);
        }
      }
      img.onerror = reject;
    });
  }
}

现在,我的下一步是在手机(Android或iOS)中测试调整大小功能,看看照片最终大小的结果。

相关问题