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

EXIF Orientation bug #559

Open
ziem opened this issue Mar 4, 2014 · 37 comments
Open

EXIF Orientation bug #559

ziem opened this issue Mar 4, 2014 · 37 comments
Labels

Comments

@ziem
Copy link

ziem commented Mar 4, 2014

Hello,
I'm using UIL 1.9.1 in my recent project. I saw that UIL is now supporting EXIF orientation #172 but I encountered issue when loading photos from SD card. In my application image is rotated by 90 degrees, but in Android gallery everything is ok.

Screens:

Code:
ImageLoader.getInstance().displayImage("file:///" + currentPhotoAbsolutePath, imageView, ImageLoaderOptions.GALLERY);

public static DisplayImageOptions GALLERY = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.build();

According to #172 (comment) it should work because I'm loading local files.

The problem occurs on:

  • Samsung Galaxy S (Cyanogenmod 11)
  • Xperia s LT26i (Android 4.1.2)
@grine4ka
Copy link

grine4ka commented Mar 4, 2014

Hi, @ziem
I consider this is not an issue. Have you tried to set considerExifParams(true) and cacheOnDisc(true) to your DisplayImageOption which you use in ImageLoader.displayImage() method?

@ziem
Copy link
Author

ziem commented Mar 4, 2014

You are right. I overlooked it. considerExifParams(true) solved my problem, thanks.

@ziem ziem closed this as completed Mar 4, 2014
@swatigoel
Copy link

It really helped me to solve this problem.

Thanks a lot. This is really awesome library.

@swatigoel swatigoel mentioned this issue Apr 9, 2014
@carl1990
Copy link

hi :I used the 1.9.2 jar and set considerExifParams(true) and cacheOnDisc(true) but this problem is also exist

@ihenk
Copy link

ihenk commented Nov 13, 2014

@carl1990 I have the same problem

@nostra13
Copy link
Owner

Can you provide image URL which is displayed wrong?

@carl1990
Copy link

sorry! I am in debug environment use company intranet,so the url u can not access.

@ihenk
Copy link

ihenk commented Nov 16, 2014

before is wrong

    public static DisplayImageOptions getDefaultDisplayImageOptions(
            Context context) {
        return new DisplayImageOptions.Builder()
                .showImageOnLoading(R.drawable.ic_default)
                .showImageForEmptyUri(R.drawable.ic_default)
                .showImageOnFail(R.drawable.ic_default)
                .cacheInMemory(true)
                .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
                .cacheOnDisk(true)
                .considerExifParams(true)
                .displayer(
                        new RoundedBitmapDisplayer(context.getResources()
                                .getDimensionPixelSize(R.dimen.icon_rounded)))
                .build();
    }

after is right

    public static DisplayImageOptions getDefaultDisplayImageOptions(
            Context context) {
        return new DisplayImageOptions.Builder()
                .showImageOnLoading(R.drawable.ic_default)
                .showImageForEmptyUri(R.drawable.ic_default)
                .showImageOnFail(R.drawable.ic_default)
                .cacheInMemory(true)
                .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
                .cacheOnDisk(true)
                .considerExifParams(false)
                .displayer(
                        new RoundedBitmapDisplayer(context.getResources()
                                .getDimensionPixelSize(R.dimen.icon_rounded)))
                .build();
    }

@ihenk
Copy link

ihenk commented Nov 16, 2014

When I set "considerExifParams (true)",the picture displayed on the phone in the wrong direction.But when I open the SD card cache files and found the picture in the right direction,this is really incredible.

After several attempts, I set "considerExifParams (false)",the picture displayed on the phone in the right direction.
notes:
(1) My program set the phone to force portrait.
(2) Only a few pictures displayed incorrectly direction.
(3) I use the jar version 1.9.3.

@nostra13
Copy link
Owner

@ihenk I tested your link and realized this weird behavior. It seems this image is rotated during decoding into Bitmap. I'll investigate this case.

@nostra13 nostra13 added the Bug label Nov 20, 2014
@nostra13 nostra13 reopened this Nov 20, 2014
@trungp
Copy link

trungp commented May 13, 2015

I faced this issue now. I also try considerExifParams on both true and false but the image still rotate 90 degree.
I use version 1.9.3. Here is my display image configure:

 mDisplayImageOptions = new DisplayImageOptions.Builder()
                .cacheInMemory(true)
                .imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
                .bitmapConfig(Bitmap.Config.ARGB_4444)
                .considerExifParams(false)
                .build();

Can someone help me to point out the issue here?

@vivaladiem
Copy link

I also meet the problem.
I'm making gallery feature, so I need to load images from MediaStore.
Original image files works well when I set considerExifParams to true.(otherwise it rotated wrongly)

But when I use MediaStore.Image.Thumbnail.Data, the Image rotated wrongly even though I set considerExifParams to true.

I also set cacheOnDisk, but it doesn't solve the problem.

@swatigoel
Copy link

To make gallery for images, I am using below code to query Media Store:
final String[] columns = { MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID,
MediaStore.Images.Media.MIME_TYPE, MediaStore.Images.Media.DISPLAY_NAME, MediaStore.Images.Media.SIZE};
final String orderBy = MediaStore.Images.Media._ID;
Cursor imageCursor = managedQuery(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, columns,
null, null, orderBy);
if (imageCursor != null && imageCursor.getCount() > 0) {

                while (imageCursor.moveToNext()) {
                    CustomGalleryItem item = new CustomGalleryItem();

                    int dataColumnIndex = imageCursor
                            .getColumnIndex(MediaStore.Images.Media.DATA);

                    item.sdcardPath = imageCursor.getString(dataColumnIndex);

                    int mimeTypeColumnIndex = imageCursor.getColumnIndex(MediaStore.Images.Media.MIME_TYPE);
                    item.mimeType = imageCursor.getString(mimeTypeColumnIndex);

                    int idColumnIndex = imageCursor.getColumnIndex(MediaStore.Images.Media._ID);
                    item.id = imageCursor.getString(idColumnIndex);

                    int nameColumnIndex = imageCursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME);
                    item.fileName = imageCursor.getString(nameColumnIndex);

                    int sizeColumnIndex = imageCursor.getColumnIndex(MediaStore.Images.Media.SIZE);
                    item.fileSize = imageCursor.getString(sizeColumnIndex);

                    if(selectedList != null && selectedList.size() > 0) {
                        for(CustomGalleryItem selectedItem : selectedList) {
                            if(selectedItem.id.equals(item.id)) {
                                item.isSeleted = true;
                                break;
                            }
                        }
                    }
                    galleryList.add(item);
                }
            }

To initialize Image Loader, I have used below code:

DisplayImageOptions defaultOptions = new DisplayImageOptions.Builder()
.imageScaleType(ImageScaleType.EXACTLY_STRETCHED)
.bitmapConfig(Bitmap.Config.RGB_565)
.considerExifParams(true).build();
ImageDecoder smartUriDecoder = new SmartUriDecoder(this, getContentResolver(), new BaseImageDecoder(false));

    ImageLoaderConfiguration.Builder builder = new ImageLoaderConfiguration.Builder(
            this).defaultDisplayImageOptions(defaultOptions).memoryCache(
                    new WeakMemoryCache())
                    .imageDecoder(smartUriDecoder);

    ImageLoaderConfiguration config = builder.build();
    ImageLoader imageLoader = ImageLoader.getInstance();
    imageLoader.init(config);

I have written custom ImageDecoder because Universal Image loader works properly to show image thumbnail. But I wanted to show thumbnail for videos, audios as well.

I am using "universal-image-loader-1.9.2-SNAPSHOT-with-sources"

@antonderevyanko
Copy link

The same issue for me. Both
.considerExifParams(false)
and
.considerExifParams(true)

leads to the same result - not properly rotated photo for portrait made images. Landscape photo is shown properly.

universal-image-loader:1.9.4

@RubydulAhsan
Copy link

Hello i faced the problem in U.I.L. V-1.9.4.Please share the findings and fix the bug.I think it is one of the major bug of this library as they offered that feature with a heavy note.

@Cedriga
Copy link

Cedriga commented Jun 15, 2015

Until the problem is fixed, I used Picasso. It automatically solves this.

@carl1990
Copy link

@Cedriga The Picasso has the same problem in SAMSUNG NOTE III with android 4.4

@burakicel
Copy link

Actually .considerExifParams(true) works for me. However make sure that you setup options and pass them to ImageLoader on any activity where you display images, Gallery, ImageDetail etc... Here is my code:

DisplayImageOptions options = new DisplayImageOptions.Builder()
                .showImageOnLoading(R.drawable.blank)
                .showImageForEmptyUri(R.drawable.blank)
                .showImageOnFail(R.drawable.blank)
                .cacheInMemory(true)
                .cacheOnDisk(true)
                .considerExifParams(true)
                .bitmapConfig(Bitmap.Config.RGB_565)
                .build();

imageLoader.displayImage(GalleryActivity.mThumbIds[position] ,imageView, options);

@Dineshcg
Copy link

My activity view is in landscape mode.

I am using all but still image is set rotate on image view.

options = new DisplayImageOptions.Builder()
.showImageOnLoading(android.R.color.white)
.showImageForEmptyUri(android.R.color.white)
.showImageOnFail(android.R.color.white)
.imageScaleType(ImageScaleType.EXACTLY)
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();

The same issue for me. Both
.considerExifParams(false)
and
.considerExifParams(true)

@surajdubey
Copy link

It's more of a compatibility issue in KitKat, Lollipop I think.
Here is another thread square/picasso#579
I'm using Picasso and having this issue.
I'll use and see if UIL gives solution.

@rx123rx
Copy link

rx123rx commented Jan 21, 2016

you need override the BaseImageDecoder.class and override the canDefineExifParams method,add image/png mimetype,then everything is ok

@FireZenk
Copy link

FireZenk commented Apr 1, 2016

Is this solved?

@dikevin0512
Copy link

sorry ,no...

------------------ 原始邮件 ------------------
发件人: "Jorge Garrido";notifications@github.com;
发送时间: 2016年4月1日(星期五) 下午3:22
收件人: "nostra13/Android-Universal-Image-Loader"Android-Universal-Image-Loader@noreply.github.com;

主题: Re: [nostra13/Android-Universal-Image-Loader] EXIF Orientation bug(#559)

Is this solved?


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub

@rx123rx
Copy link

rx123rx commented Apr 1, 2016

i got the reason,that is because of mimeType in method canDefineExifParams(String imageUri, String mimeType) of the class BaseImageDecoder you should add "image/png" in this method.
I did it like this,and it works.

在 2016-04-01 15:25:18,"dylan" notifications@github.com 写道:
sorry ,no...

------------------ 原始邮件 ------------------
发件人: "Jorge Garrido";notifications@github.com;
发送时间: 2016年4月1日(星期五) 下午3:22
收件人: "nostra13/Android-Universal-Image-Loader"Android-Universal-Image-Loader@noreply.github.com;

主题: Re: [nostra13/Android-Universal-Image-Loader] EXIF Orientation bug(#559)

Is this solved?


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub


You are receiving this because you commented.
Reply to this email directly or view it on GitHub

@FireZenk
Copy link

FireZenk commented Apr 1, 2016

Some sample code @rx123rx ?

@dikevin0512
Copy link

thanks ,i try it later...

------------------ 原始邮件 ------------------
发件人: "Monkey.D.Ren";notifications@github.com;
发送时间: 2016年4月1日(星期五) 下午3:42
收件人: "nostra13/Android-Universal-Image-Loader"Android-Universal-Image-Loader@noreply.github.com;
抄送: "kevin"274355280@qq.com;
主题: Re: [nostra13/Android-Universal-Image-Loader] EXIF Orientation bug(#559)

i got the reason,that is because of mimeType in method canDefineExifParams(String imageUri, String mimeType) of the class BaseImageDecoder you should add "image/png" in this method.
I did it like this,and it works.

在 2016-04-01 15:25:18,"dylan" notifications@github.com 写道:
sorry ,no...

------------------ 原始邮件 ------------------
发件人: "Jorge Garrido";notifications@github.com;
发送时间: 2016年4月1日(星期五) 下午3:22
收件人: "nostra13/Android-Universal-Image-Loader"Android-Universal-Image-Loader@noreply.github.com;

主题: Re: [nostra13/Android-Universal-Image-Loader] EXIF Orientation bug(#559)

Is this solved?


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub


You are receiving this because you commented.
Reply to this email directly or view it on GitHub

You are receiving this because you commented.
Reply to this email directly or view it on GitHub

@rx123rx
Copy link

rx123rx commented Apr 1, 2016

private boolean canDefineExifParams(String imageUri, String mimeType) {
if (mimeType == null) {
return false;
}
return ("image/jpeg".equalsIgnoreCase(mimeType) || "image/png".equalsIgnoreCase(mimeType)) && (Scheme.ofUri(imageUri) == Scheme.FILE);
}

because of the suffix of the pictures in the cache is .png,i just override this method like this.

在 2016-04-01 15:44:36,"Jorge Garrido" notifications@github.com 写道:

Some sample code @rx123rx ?


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

@dikevin0512
Copy link

ha ha ,thanks,may i take your contact information?

------------------ 原始邮件 ------------------
发件人: "Monkey.D.Ren";notifications@github.com;
发送时间: 2016年4月1日(星期五) 下午3:52
收件人: "nostra13/Android-Universal-Image-Loader"Android-Universal-Image-Loader@noreply.github.com;
抄送: "kevin"274355280@qq.com;
主题: Re: [nostra13/Android-Universal-Image-Loader] EXIF Orientation bug(#559)

private boolean canDefineExifParams(String imageUri, String mimeType) {
if (mimeType == null) {
return false;
}
return ("image/jpeg".equalsIgnoreCase(mimeType) || "image/png".equalsIgnoreCase(mimeType)) && (Scheme.ofUri(imageUri) == Scheme.FILE);
}

because of the suffix of the pictures in the cache is .png,i just override this method like this.

在 2016-04-01 15:44:36,"Jorge Garrido" notifications@github.com 写道:

Some sample code @rx123rx ?


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

You are receiving this because you commented.
Reply to this email directly or view it on GitHub

@rx123rx
Copy link

rx123rx commented Apr 1, 2016

does it work?

在 2016-04-01 15:45:42,"dylan" notifications@github.com 写道:
thanks ,i try it later...

------------------ 原始邮件 ------------------
发件人: "Monkey.D.Ren";notifications@github.com;
发送时间: 2016年4月1日(星期五) 下午3:42
收件人: "nostra13/Android-Universal-Image-Loader"Android-Universal-Image-Loader@noreply.github.com;
抄送: "kevin"274355280@qq.com;
主题: Re: [nostra13/Android-Universal-Image-Loader] EXIF Orientation bug(#559)

i got the reason,that is because of mimeType in method canDefineExifParams(String imageUri, String mimeType) of the class BaseImageDecoder you should add "image/png" in this method.
I did it like this,and it works.

在 2016-04-01 15:25:18,"dylan" notifications@github.com 写道:
sorry ,no...

------------------ 原始邮件 ------------------
发件人: "Jorge Garrido";notifications@github.com;
发送时间: 2016年4月1日(星期五) 下午3:22
收件人: "nostra13/Android-Universal-Image-Loader"Android-Universal-Image-Loader@noreply.github.com;

主题: Re: [nostra13/Android-Universal-Image-Loader] EXIF Orientation bug(#559)

Is this solved?


You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub


You are receiving this because you commented.
Reply to this email directly or view it on GitHub

You are receiving this because you commented.
Reply to this email directly or view it on GitHub


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

@FireZenk
Copy link

FireZenk commented Apr 1, 2016

@rx123rx Seems to work on Samsung devices... but Sony fails

@rx123rx
Copy link

rx123rx commented Apr 1, 2016

i think u can watch the logcat ,have a look what kind of suffix of the pictures in the cache then add this kind of mimeType in that method.
Maybe it works.good luck!

在 2016-04-01 17:51:02,"Jorge Garrido" notifications@github.com 写道:

@rx123rx Seems to work on Samsung devices... but Sony fails


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

@rx123rx
Copy link

rx123rx commented Apr 1, 2016

And it works on my HTC M8 .

在 2016-04-01 17:51:02,"Jorge Garrido" notifications@github.com 写道:

@rx123rx Seems to work on Samsung devices... but Sony fails


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub

@tusharpandey-kiwi
Copy link

@nostra13 : I have tried this section of logic and it works in mine case.

http://stackoverflow.com/a/39226824/2382964

@im4eversmrt
Copy link

I just faced the same problem on samsung devices but considerExifParams(true) just solved it.

@yogeshmishrikotkar
Copy link

Hello ,

I am using this universal image loader lib for caching images.
But when I received the image i am adding the encryption on file and decryption while the decode is called.
I am facing issue of Samsung devices , As my image is get rotated.
exif param is not applying at this time. please help if anyone has fixed this issue .

my code is :
For Encryption is
`@Override
public boolean save(String imageUri, InputStream imageDataStream, IoUtils.CopyListener listener) throws IOException {

    InputStream imageStream = EncryptionHandler.getSecureInputStream(imageDataStream, EncryptionHandler.MODE_ENCRYPT, ImageDbEncryptionAlgo.getInstance());
    File imageFile = getFile(imageUri);
    File tmpFile = new File(imageFile.getAbsolutePath() + TEMP_IMAGE_POSTFIX);
     boolean loaded = false;
    try {
        OutputStream os = new BufferedOutputStream(new FileOutputStream(tmpFile), bufferSize);
        try {
            loaded = IoUtils.copyStream(imageStream, os, listener, bufferSize);
          } finally {
            IoUtils.closeSilently(os);
        }
    } finally {
        if (loaded && !tmpFile.renameTo(imageFile)) {
            loaded = false;
        }
           if (!loaded) {
            tmpFile.delete();
        }
        if(imageStream !=null){
            IoUtils.closeSilently(imageStream);
        }
        if(imageDataStream !=null){
            IoUtils.closeSilently(imageDataStream);
        }
        imageStream =null;
        imageDataStream =null;
    }
    return loaded;
}
  @Override
   public boolean save(String imageUri, Bitmap bitmap) throws IOException {
       File imageFile = getFile(imageUri);
       File tmpFile = new File(imageFile.getAbsolutePath() + TEMP_IMAGE_POSTFIX);
       OutputStream os = new BufferedOutputStream(new FileOutputStream(tmpFile), bufferSize);
       boolean savedSuccessfully = false;
       try {
           savedSuccessfully = EncryptionHandler.encryptBitmap(bitmap, tmpFile.getAbsolutePath(),ImageDbEncryptionAlgo.getInstance());
        } finally {
           IoUtils.closeSilently(os);
           if (savedSuccessfully && !tmpFile.renameTo(imageFile)) {
               savedSuccessfully = false;
           }
            if (!savedSuccessfully) {
               tmpFile.delete();
           }
       }
       bitmap.recycle();
       return savedSuccessfully;
   }
`

For decryption code is :

public Bitmap decode(ImageDecodingInfo decodingInfo) throws IOException {
        Bitmap decodedBitmap;
        ImageFileInfo imageInfo;
        InputStream decryptedStream =null;
          InputStream imageStream = getImageStream(decodingInfo);
        if (imageStream == null) {
            L.e("Error no image stream", decodingInfo.getImageKey());
            return null;
        }
        try {
            String imageKey = decodingInfo.getImageUri();


            boolean isLocalImage= isLocalCachedFile(imageKey);
            if (isLocalImage) {
                decryptedStream = EncryptionHandler.getSecureInputStream(imageStream, EncryptionHandler.MODE_DECRYPT, ImageDbEncryptionAlgo.getInstance());
            } else {
                decryptedStream = imageStream;
            }

             
            imageInfo = defineImageSizeAndRotation(decryptedStream, decodingInfo);
            
            decryptedStream = resetStream(decryptedStream, decodingInfo);
            
            BitmapFactory.Options decodingOptions = prepareDecodingOptions(imageInfo.imageSize, decodingInfo);
            decodedBitmap = BitmapFactory.decodeStream(decryptedStream, null, decodingOptions);
        } finally {
            IoUtils.closeSilently(decryptedStream);
            IoUtils.closeSilently(imageStream);
        }

        if (decodedBitmap == null) {
            L.e(ERROR_CANT_DECODE_IMAGE, decodingInfo.getImageKey());
        } else {
            decodedBitmap = considerExactScaleAndOrientatiton(decodedBitmap, decodingInfo, imageInfo.exif.rotation,
                    imageInfo.exif.flipHorizontal);
        }
                return decodedBitmap;
    }

@shubham-raitka
Copy link

I used this;-
DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheInMemory(true)
.cacheOnDisk(true)
.displayer(new SimpleBitmapDisplayer())
.resetViewBeforeLoading(true)
.considerExifParams(true)
.build();

considerExifParams(true) worked for me.

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

No branches or pull requests