Coder Social home page Coder Social logo

Comments (23)

John-Goff avatar John-Goff commented on May 21, 2024 5

Hi! We recently had the same issue described above. After searching through a few different libraries that all had the same underlying issue, I've discovered the solution. You need to make sure that you pass the CORRECT mime type to canvas.toBlob. By correct I mean the same image type as the file that was originally uploaded. The best way to do this is to check the magic bytes of the file, falling back to the file's self reported type. Reason for this is the self reported type can be wrong. Here's an example:

const fr = new FileReader();
fr.onload = (e) => {
  this.uploadedPhoto = e.target.result;
};
fr.onloadend = (e) => {
  if (!e || !e.target || !e.target.result) return;
  const arr = (new Uint8Array(e.target.result)).subarray(0, 4);
  let header = "";
  for (let i = 0; i < arr.length; i++) {
     header += arr[i].toString(16);
  }
  switch (header) {
    case "89504e47":
      this.mimeType = "image/png";
      break;
    case "47494638":
      this.mimeType = "image/gif";
      break;
    case "ffd8ffe0":
    case "ffd8ffe1":
    case "ffd8ffe2":
    case "ffd8ffe3":
    case "ffd8ffe8":
      this.mimeType = "image/jpeg";
      break;
    default:
      this.mimeType = this.value.type;
      break;
  }
};
fr.readAsDataURL(this.value);

Where this.value is a File object and this.uploadedPhoto is then passed to cropper like so: <cropper :src="uploadedPhoto" @change="cropImage" />. Then in the cropImage function we use the mimeType we saved earlier:

cropImage({ canvas }) {
  if (canvas) {
    canvas.toBlob(blobData => {
      this.croppedPhoto = blobData;
    }, this.mimeType)
  } else {
    this.croppedPhoto = null;
  }
}

With all that, you can then turn this.croppedPhoto, which is a Blob, into File with the same filename and extension as the original image for uploading to a server:

new File([this.croppedPhoto], this.value.name)

With all this, I do still see some increase in image size between the original file and the size of file sent to my server if I do not crop it at all, but I think this is due to converting the file to base64. Not sure if there is a way around this, but as the files are only increasing by 10%-20% and not by 500% as it was before, I'm fine with this solution. Hope this helps someone!

from vue-advanced-cropper.

Norserium avatar Norserium commented on May 21, 2024 3

Hello, @AlbertRAR! I've updated the documentation and added the section 'Upload image to a server'.

from vue-advanced-cropper.

Norserium avatar Norserium commented on May 21, 2024 2

@LaKing, I've fixed the links in my messages. The section names was changed.

from vue-advanced-cropper.

Norserium avatar Norserium commented on May 21, 2024 2

I've extended the uploading example in the documentation to address this issue. I assume it would be helpful in preventing the described problem.

from vue-advanced-cropper.

AlbertRAR avatar AlbertRAR commented on May 21, 2024 1

Hi @Norserium !
Thanks for the quick response and the example, I appreciated!

from vue-advanced-cropper.

Norserium avatar Norserium commented on May 21, 2024

Hello, @BenFranklin-1776!

I suppose, you convert a cropped image into a data URI. Could you try to set an another type?
For example, canvas.toDataURL('image/jpeg').

from vue-advanced-cropper.

BenFranklin-1776 avatar BenFranklin-1776 commented on May 21, 2024

Good day. Thank you for the reply. We did try to set another type. I had tried image/jpeg yesterday and still got very large upload -- server will now accept a huge upload. I think there is also a timeout with the request with that. But in any even it shouldn't be sending an increasing in size upload to the server. Here's the code attached.
cropper_code.txt
)

from vue-advanced-cropper.

Norserium avatar Norserium commented on May 21, 2024

Could you explain, why do you convert dataURL to blob by this way?

        const dataUrl = this.$refs.cropper.getCroppedCanvas().toDataURL()
        const blobBin = atob(dataUrl.split(',')[1])
        const array = []
        for (let i = 0; i < blobBin.length; i++) {
          array.push(blobBin.charCodeAt(i))
        }
        this.rectImg = new Blob([new Uint8Array(array)], { type: 'image/png' })
        this.$emit('upload', this.squareImg, this.rectImg)

There is toBlob method (read more here)

from vue-advanced-cropper.

Norserium avatar Norserium commented on May 21, 2024

@BenFranklin-1776, any news?

from vue-advanced-cropper.

BenFranklin-1776 avatar BenFranklin-1776 commented on May 21, 2024

Good day, Please see attached our update code that is working. However, we are still testing image size issues in what's being sent to the server. I will update when I have the info from testing.
revCropperCode.txt

from vue-advanced-cropper.

Norserium avatar Norserium commented on May 21, 2024

@BenFranklin-1776, how is your testing results?

from vue-advanced-cropper.

AlbertRAR avatar AlbertRAR commented on May 21, 2024

Hello @Norserium
Thanks for the great plugin, it works well and fits all the needs.
I understand that my question is not related to the plugin functionality but can you please demonstrate how to properly use the toBlob() method instead of toDataURL()?
Maybe you could place an example to https://norserium.github.io/vue-advanced-cropper/tutorials/recipes.html#getting-result instead of this.image = canvas.toDataURL() :)

from vue-advanced-cropper.

ettaegbe avatar ettaegbe commented on May 21, 2024

pass 'image/jpeg' as the second parameter.
canvas.toBlob(callback,'image/jpeg')

from vue-advanced-cropper.

pnutmath avatar pnutmath commented on May 21, 2024

Same issue we find 1.8MB image goes to around 24MB.

from vue-advanced-cropper.

Norserium avatar Norserium commented on May 21, 2024

@pnutmath, did you try the recommendations above? Look at the upload example in the documentation also. I suppose that it's not the issue of this library.

from vue-advanced-cropper.

acurvers avatar acurvers commented on May 21, 2024

I also have this issue,
trying several recommendations from above did not help me. but if you find a solution @pnutmath i gladly hear about it.

from vue-advanced-cropper.

Norserium avatar Norserium commented on May 21, 2024

@acurvers, could you provide more details? How much is image weight before upload and after upload? Could you send the source code?

from vue-advanced-cropper.

pnutmath avatar pnutmath commented on May 21, 2024

@Norserium , @acurvers - if we specified file type correctly while getting data URL canvas.toDataURL('image/<type>') it does not produce exponential size, but definately not at best too.

This is specifically with high defination images

Can we identify it using library only thet helpes user of this library?

from vue-advanced-cropper.

chrislebaron avatar chrislebaron commented on May 21, 2024

@John-Goff's solution worked well for me with a few exceptions. The switch case for finding the MIME type didn't work, so I took it out.

from vue-advanced-cropper.

LaKing avatar LaKing commented on May 21, 2024

https://norserium.github.io/ has only 404 pages on the links provided here in this thread ... is this temporary?

from vue-advanced-cropper.

9mm avatar 9mm commented on May 21, 2024

I'd also like to add to this for anyone reading this that you should also pass the 3rd argument of toBlob for image quality. It says "any value between 0 and 1" however it doesn't say if its inclusive of 1 or 0.99 only.

from vue-advanced-cropper.

9mm avatar 9mm commented on May 21, 2024

It seems that its inclusive of 1 even though it says "between", so a value of 1 is 100% quality. One oddity is I notice setting it at 0.99 results in enormous drop in file size...

from vue-advanced-cropper.

Norserium avatar Norserium commented on May 21, 2024

I assume it's time to close this issue. Feel free to reopen, if anything comes up.

from vue-advanced-cropper.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.