Поворот изображения в Angular4

1

Перед загрузкой на мой сервер я пытаюсь повернуть изображение. Шаги, которые я сделал до сих пор:

  1. Преобразуйте изображение в Base64.
  2. Вращение строки base64 с помощью холста.
  3. Преобразование повернутого Base64 в изображение.

Но я не могу преобразовать его обратно в формат изображения. Окончательный файл изображения (после ротации) не может быть загружен, поскольку он является блобом.

Не могли бы вы рассказать мне, как преобразовать мою повернутую строку Base64 в файл изображения, чтобы я мог создать blob и загрузить его.

Я полагаю, что моя функция вращения не является подходящей, поскольку я пытался ее преобразовать и взял преобразованную строку base64 для просмотра на https://codebeautify.org/base64-to-image-converter и дал мне пустой файл (черный файл изображения).

Происхождение этой проблемы заключается в том, что пользователь нажимает изображение на iOS или Android и загружает его изображение вбок. Чтобы исправить это, я пытаюсь повернуть изображение в соответствии с его ориентацией EXIF.

function detectFiles(event) {
    this.getOrientation(event.target.files[0], function (orientation) {
        this.imageOrientation = orientation;
    }.bind(this));
    console.log('the original image data', event.target.files);
    this.selectedFiles = event.target.files;

    // SAS : Converting the selected image to Base64 for rotation.
    const reader = new FileReader();
    reader.onloadend = (e) => {
        this.base64Data = reader.result;
        const rotatedData = this.rotateBase64Image(this.base64Data);

        // SAS: Calling the data uri to blob
        const selFile = this.dataURItoBlob(rotatedData);
        this.uploadFiles(selFile);
    }

    reader.readAsDataURL(event.target.files[0]);

}

// SAS: Rotate the image.
function rotateBase64Image(base64ImageSrc) {
    const canvas = document.createElement('canvas');
    const img = new Image();
    img.onload = function () {
        canvas.width = img.width;
        canvas.height = img.height;
        console.log('image height and width', canvas.width , canvas.height);
    }
    img.src = base64ImageSrc;
    const context = canvas.getContext('2d');
    context.translate((img.width), (img.height));
    // context.rotate(180 * (Math.PI / 180));
    context.rotate(90);
    context.drawImage(img, 0, 0);
    console.log(canvas);
    console.log('the rotated image', canvas.toDataURL());
    return canvas.toDataURL();
}

// SAS: Data URI to Blob
function dataURItoBlob(dataURI) {
    // convert base64 to raw binary data held in a string
    // doesn't handle URLEncoded DataURIs
    const byteString = atob(dataURI.split(',')[1]);

    // separate out the mime component
    const mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]

    // write the bytes of the string to an ArrayBuffer
    const ab = new ArrayBuffer(byteString.length);

    // create a view into the buffer
    const ia = new Uint8Array(ab);

    // set the bytes of the buffer to the correct values
    for (let i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
    }

    // write the ArrayBuffer to a blob, and you're done
    const blob = new Blob([ab], {type: mimeString});
    console.log('the value of the blob', blob);
    return blob;
}

И после этого я пытаюсь загрузить данные, используя следующую функцию, которая принимает файл изображения.

uploadFiles(selFile) {
    // SAS: Setting the 'image uploaded flag' to be retrieved in quick post to prevent duplicate placeholders.

    // const file = this.selectedFiles.item(0);
    const file = selFile;
    this.currentUpload = new Upload(file);

// This is the API call to upload the file.
    this.storageApiService.createBlob(file).subscribe((response) => {

      console.log(response);
    }, (error) => {
      console.log(error);
    });
  }
}
Теги:
angular
image

1 ответ

0

Вы можете позаботиться о вращении exif для них, чтобы они не могли поворачивать изображение

Я создал библиотеку, которой никогда не приходилось использовать filerader под названием screw-filereader с дополнительным бонусом создания изображения из blobs очень легко, просто вызвав blob.image().then(success, fail) и он позаботится об изображениях exif вращение для вас.

// unrelevant code (just to get a rotated image with exif metadata)
var exifImage = 'https://cors-anywhere.herokuapp.com/http://duckz.serveblog.net/risorse/foto/francia/P1831_21-02-10.jpg'

fetch(exifImage)
  .then(res => res.blob())
  .then(blob => {

    // just to show the problem you have with your image
    const objectURL = URL.createObjectURL(blob)
    const img = new Image()
    img.src = objectURL
    document.body.appendChild(img)
    
    // what screw-filereader can do (auto rotate based on exif data)
    // will resolve at img.onload event with a new img element
    // will also cast a error if blob isn't a image (img.onerror)
    // this is what you need...
    blob.image().then(img => {
     
      // convert image back to blob
      var canvas = document.createElement('canvas')
      canvas.width = img.width
      canvas.height = img.height
      const ctx = canvas.getContext('2d')
      ctx.drawImage(img, 0, 0)
      canvas.toBlob(uploadFiles)
      
      // just to show the rotated image 
      document.body.appendChild(img)
    })
  })
  
function uploadFiles(blob) {
  // upload blob
}
img {
  width: 100px
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/index.min.js"></script>

Бонусный наконечник, используйте canvas.toBlob вместо использования данныхURItoBlob

  • 0
    Спасибо за ваш ценный ответ, это определенно поможет многим людям, сталкивающимся с той же проблемой. Хотя по какой-то причине, когда я пытаюсь использовать это, но это выдает мне ошибку "свойство image не существует в типе blob" ..

Ещё вопросы

Сообщество Overcoder
Наверх
Меню