Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting a NoSuchMethodError: The getter 'exif' was called on null. when converting a .png to .jpeg #67

Closed
pablote opened this issue May 27, 2018 · 23 comments

Comments

@pablote
Copy link

pablote commented May 27, 2018

This is my code. Image comes directly from the camera using the image_picker plugin:

var imageFile = await ImagePicker.pickImage(source: ImageSource.camera);

try {
      var pngImage = image.decodePng(imageFile.readAsBytesSync());
      print("## Image decoded fine");
      var jpegFile = new File(path.join(tempPath, 'upload.jpg'));
      print("## 1");
      var jpegBytes = image.encodeJpg(pngImage);
      print("## 1B");
      jpegFile.writeAsBytesSync(jpegBytes);
      print("## 2");
      imageFile = jpegFile;
      print("## 3");
    } catch (error) {
      print("## ERROR");
      print(error);
      print("## ERROR DONE");
    }

And it logs to console:

I/flutter (15417): ## Camera filename/storage/emulated/0/Android/data/com.scanrapp/files/Pictures/3967201f-c26f-49db-8d04-09929bace1f21282873232.png
I/flutter (15417): ## Image decoded fine
I/flutter (15417): ## 1
I/flutter (15417): ## ERROR
I/flutter (15417): NoSuchMethodError: The getter 'exif' was called on null.
I/flutter (15417): Receiver: null
I/flutter (15417): Tried calling: exif
I/flutter (15417): ## ERROR DONE

If instead of decodePng I use decodeImage, then it doesn't fail. But the generated image seems invalid, I can't open it with any application.

@brendan-duncan
Copy link
Owner

brendan-duncan commented May 27, 2018 via email

@pablote
Copy link
Author

pablote commented May 27, 2018

Just did some more testing. decodePng returns null for my image, so that explains the The getter 'exif' was called on null error, not sure why that returns null though. Using decodeImage works, and returns an Image object. Although it then seems to generate a malformed jpeg.

thanks!

@brendan-duncan
Copy link
Owner

brendan-duncan commented May 27, 2018 via email

@pablote
Copy link
Author

pablote commented May 27, 2018

Thanks for the help, I found something new (sorry for all the back and forth). ImagePicker plugin saves a .png file, but the content is actually is a JPEG image (flutter/flutter#17947). So that explains decodePng returning null, and decodeImage working.

The malformed image it's harder to reproduce I guess, I'm uploading the image to a python backend and saving it as a file. I'm confident that part of the code works fine, cause I have no problems with other images, only the ones that go though this process. The example code might seems useless now, but I'm planning on using this to reduce the size of the file before uploading, so I'm still hoping this to work.

About error messages, the Python backend shows this when trying to open with Pillow: broken data stream when reading image file. And if it open it on my mac:
screen shot 2018-05-27 at 4 06 48 pm

@brendan-duncan
Copy link
Owner

brendan-duncan commented May 27, 2018 via email

@pablote
Copy link
Author

pablote commented May 27, 2018

Thank you very much.

upload.jpg.zip

@brendan-duncan
Copy link
Owner

Would it be possible to get the original image out of ImagePicker?

@brendan-duncan
Copy link
Owner

Looking at that jpeg, it starts off ok, has the correct tags. It gets to the EXIF tag (which I just recently added), and the file goes wrong from that point on. If I had the original file, I could determine why the EXIF block got messed up.

@brendan-duncan
Copy link
Owner

Actually, I found some jpeg exif unit test images and some of them produce corrupted output images too, so I can use those to debug with.

@brendan-duncan
Copy link
Owner

I got all of the jpegs that were generating bad output images fixed. The problem was caused by multiple exif blocks in the jpeg. Hopefully it will fix your particular issue, but I can't know for sure until you can test it.

@pablote
Copy link
Author

pablote commented May 28, 2018

Unfortunately I'm only saving the final image, not the before and after, but I'll do that tonight and get you a sample. So there's an updated version of the lib with a fix? :D I'll try that tonight too, thanks!

@brendan-duncan
Copy link
Owner

brendan-duncan commented May 28, 2018 via email

@pablote
Copy link
Author

pablote commented May 28, 2018

Attaching a before and after of the images. This is the code running in between:

await ApiClient.postDocument(this.loggedInUser, imageFile);
imageFile = await ApiClient.convertToJpeg(imageFile);
await ApiClient.postDocument(this.loggedInUser, imageFile);

  static Future<File> convertToJpeg(File imageFile) async {
    Directory tempDir = await getTemporaryDirectory();
    String tempPath = tempDir.path;

    try {
      var pngImage = image.decodeImage(imageFile.readAsBytesSync());
      print("## Image decoded fine");
      var jpegFile = new File(path.join(tempPath, 'upload.jpg'));
      print("## 1");
      var jpegBytes = image.encodeJpg(pngImage, quality: 85);
      print("## 1B");
      jpegFile.writeAsBytesSync(jpegBytes);
      print("## 2");
      return jpegFile;
    } catch (error) {
      print("## ERROR");
      print(error);
      print("## ERROR DONE");
      throw error;
    }
  }

images.zip

@brendan-duncan
Copy link
Owner

brendan-duncan commented May 28, 2018 via email

@pablote
Copy link
Author

pablote commented May 28, 2018

Another sample, this time with quality: 100. Thanks! :D

images2.zip

@brendan-duncan
Copy link
Owner

I verified it does fix the output images. I have to fix one more thing with it, but I’ll be able to push the new version this evening (after I get the kids to bed.)

@pablote
Copy link
Author

pablote commented May 29, 2018

awesome, thanks

@brendan-duncan
Copy link
Owner

I pushed the new version, 2.0.1, to pub. It was one of things where it should never have worked to begin with, I don't know what voodoo made most jpeg encoded images not be broken before this.

@pablote
Copy link
Author

pablote commented May 29, 2018

Great! Does it take a while for pub to show new versions? I was about to test this and I still see 2.0.0 as latest

@brendan-duncan
Copy link
Owner

brendan-duncan commented May 29, 2018 via email

@brendan-duncan
Copy link
Owner

I published it, and actually checked this time that it got uploaded to pub.

@pablote
Copy link
Author

pablote commented May 30, 2018

I just tested this and it's working great, thanks! :)

@pablote pablote closed this as completed May 30, 2018
@haseebnori
Copy link

I published it, and actually checked this time that it got uploaded to pub.

Hey, Can I talk to you about the issue, I'm facing same kind of problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants