Unable to load JPEG-image with BitmapFactory.decod

2019-02-15 21:50发布

问题:

I'm making an app that show a lot of images that are generated from PDF-files by Imagemagick. Some of the images, can't be loaded with BitmapFactory. It simply returns null istead of a bitmap.

The log says:

    D/skia(15101): --- decoder->decode returned false

It isn't a memory problem as some of the images with the problem is very small, and the images aren't corrupt because I can show them on any other machine. Additionally BitmapFactory is able to decode the width and height if I use

    inJustDecodeBounds = true;

in the options.

I've tried to load one of the images with an external Image Viewer (QuickPic) without luck. It also returns "Load failed", which indicates that SKIA believes the image is corrupt or at least not supported for some reason.

One of the images that doesn't work can be found here

The complete code I use to load it is here

    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(FILENAME,o);
    int width = o.outWidth;
    int height = o.outHeight;
    /* Width and height decoded successfuly */

    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o.inJustDecodeBounds = false;
    Bitmap bitmap = BitmapFactory.decodeFile(FILENAME,o2); 
    /*Bitmap is null */

Any idea what is wrong or how it can be circumvented is welcome.

回答1:

Images with CMYK colorspace, like this, cannot be decoded by Android by default so they cannot be displayed.

Niels was right, but in case you can't change that parameter on the imageMagick conversion, you can convert the CMYK image to RGB image (supported by Android). There is a library of imageMagick for Android called android-lib-magick and here is a workaround to this problem.

Just importing this library the code to transform its colorspace is quite simple:

ImageInfo info = new ImageInfo(path); // path where the CMYK image is your device
MagickImage imageCMYK = new MagickImage(info);
imageCMYK.transformRgbImage(ColorspaceType.CMYKColorspace);
Bitmap bitmap = MagickBitmap.ToBitmap(imageCMYK);

If the image is not in your device or on your SD card, you will need to download it first.

I have implemented two simple methods using android-lib-magick called "getCMYKImageFromPath" and "getCMYKImageFromURL". You can see the code here:

https://github.com/Mariovc/GetCMYKImage



回答2:

Apparently SKIA has a problem with JPG's with a CMYK-profile. The workaround for my problem was to add the parameter "-colorspace RGB" to my imagemagick conversion.