简体   繁体   English

从图库中获取并上传时,ImageView 上的图像方向已更改

[英]Image orientation is changed on ImageView When fetching from Gallery and upload

I simply want to fetch Images from gallery and upload then download from Server and set it on an ImageView on Activity.我只想从图库中获取图像并上传然后从服务器下载并将其设置在 Activity 的 ImageView 上。 The image View is placed at the center of the Activity.图像视图放置在活动的中心。 All is working fine just a screenOrientation variation problem with adjusting Image on ImageView after fetching it from Server, download and set to image View.一切正常,只是一个 screenOrientation 变化问题,在从服务器获取图像后调整 ImageView 上的图像,下载并设置为图像视图。 Please have a look over code what i am using to download Image Bitmap from Server and set it to required ImageView.请查看我用来从服务器下载图像位图并将其设置为所需的 ImageView 的代码。 It usually display rotated Image in case of portrait capturing image from Gallery or Camera.在从图库或相机拍摄人像图像的情况下,它通常显示旋转图像。 Please let me know if i am missing anything in my Code.如果我的代码中缺少任何内容,请告诉我。

package com.fedorvlasov.lazylist;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import com.example.qlique.R;
import android.os.Handler;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;

public class ImageLoader {
    MemoryCache memoryCache = new MemoryCache();
    FileCache fileCache;
    private Map<ImageView, String> imageViews = Collections
            .synchronizedMap(new WeakHashMap<ImageView, String>());
    ExecutorService executorService;
    Handler handler = new Handler();// handler to display images in UI thread

    public ImageLoader(Context context) {
        fileCache = new FileCache(context);
        executorService = Executors.newFixedThreadPool(5);
    }

    final int stub_id = R.drawable.stub;

    public void DisplayImage(String url, ImageView imageView) {
        imageViews.put(imageView, url);
        Bitmap bitmap = memoryCache.get(url);
        if (bitmap != null)
            imageView.setImageBitmap(bitmap);
        else {
            queuePhoto(url, imageView);
            imageView.setImageResource(stub_id);
        }
    }

    private void queuePhoto(String url, ImageView imageView) {
        PhotoToLoad p = new PhotoToLoad(url, imageView);
        executorService.submit(new PhotosLoader(p));
    }

    private Bitmap getBitmap(String url) {
        File f = fileCache.getFile(url);

        // from SD cache
        Bitmap b = decodeFile(f);
        if (b != null)
            return b;

        // from web
        try {
            Bitmap bitmap = null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) imageUrl
                    .openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is = conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
            Utils.CopyStream(is, os);
            os.close();
            conn.disconnect();
            bitmap = decodeFile(f);
            return bitmap;
        } catch (Throwable ex) {
            ex.printStackTrace();
            if (ex instanceof OutOfMemoryError)
                memoryCache.clear();
            return null;
        }
    }

    // decodes image and scales it to reduce memory consumption
    private Bitmap decodeFile(File f) {
        try {
            // decode image size
            BitmapFactory.Options o = new BitmapFactory.Options();
            o.inJustDecodeBounds = true;
            FileInputStream stream1 = new FileInputStream(f);
            BitmapFactory.decodeStream(stream1, null, o);
            stream1.close();

            // Find the correct scale value. It should be the power of 2.
            final int REQUIRED_SIZE = 70;
            int width_tmp = o.outWidth, height_tmp = o.outHeight;
            int scale = 1;
            while (true) {
                if (width_tmp / 2 < REQUIRED_SIZE
                        || height_tmp / 2 < REQUIRED_SIZE)
                    break;
                width_tmp /= 2;
                height_tmp /= 2;
                scale *= 2;
            }

            // decode with inSampleSize
            BitmapFactory.Options o2 = new BitmapFactory.Options();
            o2.inSampleSize = scale;
            FileInputStream stream2 = new FileInputStream(f);
            Bitmap bitmap = BitmapFactory.decodeStream(stream2, null, o2);
            stream2.close();
            return bitmap;
        } catch (FileNotFoundException e) {
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    // Task for the queue
    private class PhotoToLoad {
        public String url;
        public ImageView imageView;

        public PhotoToLoad(String u, ImageView i) {
            url = u;
            imageView = i;
        }
    }

    class PhotosLoader implements Runnable {
        PhotoToLoad photoToLoad;

        PhotosLoader(PhotoToLoad photoToLoad) {
            this.photoToLoad = photoToLoad;
        }

        @Override
        public void run() {
            try {
                if (imageViewReused(photoToLoad))
                    return;
                Bitmap bmp = getBitmap(photoToLoad.url);
                memoryCache.put(photoToLoad.url, bmp);
                if (imageViewReused(photoToLoad))
                    return;
                BitmapDisplayer bd = new BitmapDisplayer(bmp, photoToLoad);
                handler.post(bd);
            } catch (Throwable th) {
                th.printStackTrace();
            }
        }
    }

    boolean imageViewReused(PhotoToLoad photoToLoad) {
        String tag = imageViews.get(photoToLoad.imageView);
        if (tag == null || !tag.equals(photoToLoad.url))
            return true;
        return false;
    }

    // Used to display bitmap in the UI thread
    class BitmapDisplayer implements Runnable {
        Bitmap bitmap;
        PhotoToLoad photoToLoad;

        public BitmapDisplayer(Bitmap b, PhotoToLoad p) {
            bitmap = b;
            photoToLoad = p;
        }

        public void run() {
            if (imageViewReused(photoToLoad))
                return;
            if (bitmap != null)
                photoToLoad.imageView.setImageBitmap(bitmap);
            else
                photoToLoad.imageView.setImageResource(stub_id);
        }
    }

    public void clearCache() {
        memoryCache.clear();
        fileCache.clear();
    }
}

First check the Orientation of an Image首先检查图像的Orientation

public static int getExifOrientation(String filepath) {
                int degree = 0;
                ExifInterface exif = null;
                try {
                        exif = new ExifInterface(filepath);
                } catch (IOException ex) {
                        ex.printStackTrace();
                }
                if (exif != null) {
                        int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1);
                        if (orientation != -1) {
                                // We only recognise a subset of orientation tag values.
                                switch (orientation) {
                                case ExifInterface.ORIENTATION_ROTATE_90:
                                        degree = 90;
                                        break;
                                case ExifInterface.ORIENTATION_ROTATE_180:
                                        degree = 180;
                                        break;
                                case ExifInterface.ORIENTATION_ROTATE_270:
                                        degree = 270;
                                        break;
                                }

                        }
                }

                return degree;
        }

And Rotate the angle of Bitmap to that Degree.并将 Bitmap 的角度旋转到该度数。

Bitmap bitmap = YOUR_BITMAP;
    //rotate bitmap
    Matrix matrix = new Matrix();               
    matrix.postRotate(orientation);
    //create new rotated bitmap
    bitmap = Bitmap.createBitmap(bitmap, 0, 0,bitmap.getWidth(), bitmap.getHeight(), matrix, true);  
   YOUR_IMAGE_VIEW.setImageBitmap(bitmap);

One nice online tool to view the Orientation and the details EXIF information http://metapicz.com/#exif-box .一个不错的在线工具,用于查看方向和详细信息 EXIF 信息http://metapicz.com/#exif-box

It would be good if you can fix/reset the orientation at the server side(once per image) and alternatively fixing at the client side is a bit costly ( as this conversion to happen every time )如果您可以在服务器端修复/重置方向(每个图像一次),或者在客户端修复有点昂贵(因为这种转换每次都会发生),那就太好了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM