Реализуйте Glide / Fresco / Picasso для изменения размера изображений перед загрузкой в ​​Imageview, чтобы избежать проблем с OOM - PullRequest
0 голосов
/ 15 января 2020

У меня есть код, который загружает четыре изображения в просмотр изображений. Чтобы избежать проблем с OOM при загрузке больших изображений, я хочу использовать Glide / Picasso / Fresco для изменения размера перед загрузкой в ​​просмотр изображений. Обратите внимание, что он работает на маленьких изображениях, но на больших изображениях (будет введен пользователем, и, следовательно, я не могу контролировать размеры), он сразу падает, второе большое изображение выбирается для просмотра изображений в OOM. Я понимаю, что спасибо

package com.ny.a4imageswithtexts;

import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Base64;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import com.bumptech.glide.Glide;
import com.bumptech.glide.load.DecodeFormat;
import com.bumptech.glide.load.engine.Resource;
import com.bumptech.glide.request.RequestOptions;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;



public class MainActivity extends AppCompatActivity {

    Bitmap bitmap1;
    Bitmap bitmap2;
    Bitmap bitmap3;
    Bitmap bitmap4;

    private int PICK_IMAGE_REQUEST1 = 1;
    private int PICK_IMAGE_REQUEST2 = 2;
    private int PICK_IMAGE_REQUEST3 = 1;
    private int PICK_IMAGE_REQUEST4 = 2;

    boolean check = true;

    Button SelectImageGallery1;
    Button SelectImageGallery2;
    Button SelectImageGallery3;
    Button SelectImageGallery4;

    Button  UploadImageServer;

    ImageView imageView1;
    ImageView imageView2;
    ImageView imageView3;
    ImageView imageView4;

    EditText imageName1;
    EditText imageName2;
    EditText imageName3;
    EditText imageName4;

    ProgressDialog progressDialog ;

    String GetImageNameEditText1;
    String GetImageNameEditText2;
    String GetImageNameEditText3;
    String GetImageNameEditText4;

    String ImageName1 = "image_name1";
    String ImageName2 = "image_name2";
    String ImageName3 = "image_name3";
    String ImageName4 = "image_name4";

    String ImagePath1 = "image_path1";
    String ImagePath2 = "image_path2";
    String ImagePath3 = "image_path3";
    String ImagePath4 = "image_path4";

    String ServerUploadPath ="http://11111111111111111.php";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        imageView1 = findViewById(R.id.imageView1);
        imageView2 = findViewById(R.id.imageView2);
        imageView3 = findViewById(R.id.imageView3);
        imageView4 = findViewById(R.id.imageView4);

        imageName1 = findViewById(R.id.editTextImageName1);
        String strImageName1 = imageName1.getText().toString();
        if(TextUtils.isEmpty(strImageName1))
{imageName1.setError("Image Name Must Be Entered");
           }
        imageName2 = findViewById(R.id.editTextImageName2);
        String strImageName2 = imageName2.getText().toString();
        if(TextUtils.isEmpty(strImageName2))
{imageName2.setError("Image Name Must Be Entered");
            }
        imageName3 = findViewById(R.id.editTextImageName3);
        String strImageName3 = imageName3.getText().toString();
        if(TextUtils.isEmpty(strImageName3))
{imageName3.setError("Image Name Must Be Entered");
              }
        imageName4 = findViewById(R.id.editTextImageName4);
        String strImageName4 = imageName4.getText().toString();
        if(TextUtils.isEmpty(strImageName4))
{imageName4.setError("Image Name Must Be Entered");
              }


        SelectImageGallery1 = findViewById(R.id.buttonSelect1);
        SelectImageGallery2 = findViewById(R.id.buttonSelect2);
        SelectImageGallery3 = findViewById(R.id.buttonSelect3);
        SelectImageGallery4 = findViewById(R.id.buttonSelect4);

        UploadImageServer = findViewById(R.id.buttonUpload);

        SelectImageGallery1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent,
"Select Image1 From Gallery"), 1);

            }
        });

        SelectImageGallery2.setOnClickListener(new View.OnClickListener() {
              @Override
                public void onClick(View view) {
                    Intent intent = new Intent();
                    intent.setType("image/*");
                    intent.setAction(Intent.ACTION_GET_CONTENT);

startActivityForResult(Intent.createChooser(intent, "Select Image4
From Gallery"), 2);
                }
          });

        SelectImageGallery3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent,
"Select Image3 From Gallery"), 3);

            }
        });

        SelectImageGallery4.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.setType("image/*");
                intent.setAction(Intent.ACTION_GET_CONTENT);
                startActivityForResult(Intent.createChooser(intent,
"Select Image4 From Gallery"), 4);

            }
        });

        UploadImageServer.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                GetImageNameEditText1 = imageName1.getText().toString();
                GetImageNameEditText2 = imageName2.getText().toString();
                GetImageNameEditText3 = imageName3.getText().toString();
                GetImageNameEditText4 = imageName4.getText().toString();
               ImageUploadToServerFunction();
            }
        });

    }

    @Override
    protected void onActivityResult(int RC, int RQC, Intent I) {
        super.onActivityResult(RC, RQC, I);
        if (RC == 1 && RQC == RESULT_OK && I != null && I.getData() != null) {
            Uri uri = I.getData();
            RequestOptions options = new RequestOptions()
                    .format(DecodeFormat.PREFER_RGB_565)
                    .placeholder(R.drawable.ic_launcher_background)
                    .error(R.drawable.ic_launcher_background);

            Glide.with(this)
                    .setDefaultRequestOptions(options)
                    .load(uri)
                    .centerInside()
                    .into(new CustomTarget<Drawable>(512, 512) {
                        @Override
                        public void onResourceReady(@NonNull Drawable
bitmap1, @Nullable Transition<? super Drawable> transition) {
                            imageView1.setImageDrawable(bitmap1);
                        }
                        @Override
                        public void onLoadCleared(@Nullable Drawable
placeholder) {
                        }
                    });
        }
        if (RC == 2 && RQC == RESULT_OK && I != null && I.getData() != null) {
            Uri uri = I.getData();
            RequestOptions options = new RequestOptions()
                    .format(DecodeFormat.PREFER_RGB_565)
                    .placeholder(R.drawable.ic_launcher_background)
                    .error(R.drawable.ic_launcher_background);

            Glide.with(this)
                    .setDefaultRequestOptions(options)
                    .load(uri)
                    .centerInside()
                    .into(new CustomTarget<Drawable>(512, 512) {
                        @Override
                        public void onResourceReady(@NonNull Drawable
bitmap2, @Nullable Transition<? super Drawable> transition) {
                            imageView2.setImageDrawable(bitmap2);
                        }
                        @Override
                        public void onLoadCleared(@Nullable Drawable
placeholder) {
                        }
                    });
        }
        if (RC == 3 && RQC == RESULT_OK && I != null && I.getData() != null) {
            Uri uri = I.getData();
            RequestOptions options = new RequestOptions()
                    .format(DecodeFormat.PREFER_RGB_565)
                    .placeholder(R.drawable.ic_launcher_background)
                    .error(R.drawable.ic_launcher_background);

            Glide.with(this)
                    .setDefaultRequestOptions(options)
                    .load(uri)
                    .centerInside()
                    .into(new CustomTarget<Drawable>(512, 512) {
                        @Override
                        public void onResourceReady(@NonNull Drawable
bitmap3, @Nullable Transition<? super Drawable> transition) {
                            imageView3.setImageDrawable(bitmap3);
                        }
                        @Override
                        public void onLoadCleared(@Nullable Drawable
placeholder) {
                        }
                    });
        }
        if (RC == 4 && RQC == RESULT_OK && I != null && I.getData() != null) {
            Uri uri = I.getData();
            RequestOptions options = new RequestOptions()
                    .format(DecodeFormat.PREFER_RGB_565)
                    .placeholder(R.drawable.ic_launcher_background)
                    .error(R.drawable.ic_launcher_background);

            Glide.with(this)
                    .setDefaultRequestOptions(options)
                    .load(uri)
                    .centerInside()
                    .into(new CustomTarget<Drawable>(512, 512) {
                        @Override
                        public void onResourceReady(@NonNull Drawable
bitmap4, @Nullable Transition<? super Drawable> transition) {
                            imageView4.setImageDrawable(bitmap4);
                        }
                        @Override
                        public void onLoadCleared(@Nullable Drawable
placeholder) {
                        }
                    });
        }
    }
    public String getStringImage1(Bitmap bitmap1){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap1.compress(Bitmap.CompressFormat.JPEG, 80, baos);
        byte[] imageBytes = baos.toByteArray();
        String encodedImage1 = Base64.encodeToString(imageBytes,
Base64.DEFAULT);
        return encodedImage1;
    }

    public String getStringImage2(Bitmap bitmap2){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap2.compress(Bitmap.CompressFormat.JPEG, 80, baos);
        byte[] imageBytes = baos.toByteArray();
        String encodedImage2 = Base64.encodeToString(imageBytes,
Base64.DEFAULT);
        return encodedImage2;
    }
    public String getStringImage3(Bitmap bitmap3){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap3.compress(Bitmap.CompressFormat.JPEG, 80, baos);
        byte[] imageBytes = baos.toByteArray();
        String encodedImage3 = Base64.encodeToString(imageBytes,
Base64.DEFAULT);
        return encodedImage3;
    }

    public String getStringImage4(Bitmap bitmap4){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap4.compress(Bitmap.CompressFormat.JPEG, 80, baos);
        byte[] imageBytes = baos.toByteArray();
        String encodedImage4 = Base64.encodeToString(imageBytes,
Base64.DEFAULT);
        return encodedImage4;
    }


    public void ImageUploadToServerFunction(){
        final String imageName1 = GetImageNameEditText1.trim();
        final String imageName2 = GetImageNameEditText2.trim();
        final String imageName3 = GetImageNameEditText3.trim();
        final String imageName4 = GetImageNameEditText4.trim();
        final String imageView1 = getStringImage1(bitmap1);
        final String imageView2 = getStringImage2(bitmap2);
        final String imageView3 = getStringImage3(bitmap3);
        final String imageView4 = getStringImage4(bitmap4);


        class AsyncTaskUploadClass extends AsyncTask<Void,Void,String> {

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
                progressDialog =
ProgressDialog.show(MainActivity.this,"Image is Uploading","Please
Wait",false,false);
            }

            @Override
            protected void onPostExecute(String string1) {

                super.onPostExecute(string1);

                // Dismiss the progress dialog after done uploading.
                progressDialog.dismiss();

                // Printing uploading success message coming from
server on android app.

Toast.makeText(MainActivity.this,string1,Toast.LENGTH_LONG).show();

                // Setting image as transparent after done uploading.
                ImageView cleared1 = findViewById(R.id.imageView1);
                cleared1.setImageResource(android.R.color.transparent);

                ImageView cleared2 = findViewById(R.id.imageView2);
                cleared2.setImageResource(android.R.color.transparent);

                ImageView cleared3 = findViewById(R.id.imageView3);
                cleared3.setImageResource(android.R.color.transparent);

                ImageView cleared4 = findViewById(R.id.imageView4);
                cleared4.setImageResource(android.R.color.transparent);


            }
            @Override
            protected String doInBackground(Void... params) {
                ImageProcessClass imageProcessClass = new ImageProcessClass();
                HashMap<String,String> HashMapParams = new
HashMap<String,String>();
                HashMapParams.put(ImageName1, imageName1);
                HashMapParams.put(ImageName2, imageName2);
                HashMapParams.put(ImageName3, imageName3);
                HashMapParams.put(ImageName4, imageName4);
                HashMapParams.put(ImagePath1, imageView1);
                HashMapParams.put(ImagePath2, imageView2);
                HashMapParams.put(ImagePath3, imageView3);
                HashMapParams.put(ImagePath4, imageView4);

                String FinalData =
imageProcessClass.ImageHttpRequest(ServerUploadPath, HashMapParams);
                return FinalData;
            }
        }
        AsyncTaskUploadClass AsyncTaskUploadClassOBJ = new
AsyncTaskUploadClass();
        AsyncTaskUploadClassOBJ.execute();
    }

    public class ImageProcessClass{
        public String ImageHttpRequest(String
requestURL,HashMap<String, String> PData) {
            StringBuilder stringBuilder = new StringBuilder();
            try {
                URL url;
                HttpURLConnection httpURLConnectionObject ;
                OutputStream OutPutStream;
                BufferedWriter bufferedWriterObject ;
                BufferedReader bufferedReaderObject ;
                int RC ;
                url = new URL(requestURL);
                httpURLConnectionObject = (HttpURLConnection)
url.openConnection();
                httpURLConnectionObject.setReadTimeout(19000);
                httpURLConnectionObject.setConnectTimeout(19000);
                httpURLConnectionObject.setRequestMethod("POST");
                httpURLConnectionObject.setDoInput(true);
                httpURLConnectionObject.setDoOutput(true);
                OutPutStream = httpURLConnectionObject.getOutputStream();
                bufferedWriterObject = new BufferedWriter(
                        new OutputStreamWriter(OutPutStream, "UTF8"));
                bufferedWriterObject.write(bufferedWriterDataFN(PData));
                bufferedWriterObject.flush();
                bufferedWriterObject.close();
                OutPutStream.close();
                RC = httpURLConnectionObject.getResponseCode();
                if (RC == HttpsURLConnection.HTTP_OK) {
                    bufferedReaderObject = new BufferedReader(new
InputStreamReader(httpURLConnectionObject.getInputStream()));
                    stringBuilder = new StringBuilder();
                    String RC2;
                    while ((RC2 = bufferedReaderObject.readLine()) != null){
                        stringBuilder.append(RC2);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return stringBuilder.toString();
        }

        private String bufferedWriterDataFN(HashMap<String, String>
HashMapParams) throws UnsupportedEncodingException {
            StringBuilder stringBuilderObject;
            stringBuilderObject = new StringBuilder();
            for (Map.Entry<String, String> KEY : HashMapParams.entrySet()) {
                if (check)
                    check = false;
                else
                    stringBuilderObject.append("&");

stringBuilderObject.append(URLEncoder.encode(KEY.getKey(), "UTF-8"));
                stringBuilderObject.append("=");

stringBuilderObject.append(URLEncoder.encode(KEY.getValue(),
"UTF-8"));
            }

            return stringBuilderObject.toString();
        }

    }

}


'''

Ответы [ 3 ]

0 голосов
/ 15 января 2020

1- Для реализации Glide https://github.com/bumptech/glide (что я предпочитаю)

2- Для реализации Picasso https://square.github.io/picasso/#download (также сильная библиотека)

Они профессионально обрабатывают изображения. У них есть инструменты, чтобы избежать OOM, вызванного изображениями. Вы должны следовать инструкциям по их внедрению и использованию.

Но ООМ не только из-за изображений. Вся заявка должна быть соблюдена.

{ ссылка } этот пост может помочь в этом.

Редактировать: Чтобы изменить размер с Glide

Glide.with(mCtxt).load( image uri or url or drawable )
                     .error( image )
                .override(320,180)
                .centerCrop()
                .into(  imageview );
0 голосов
/ 15 января 2020

Вы должны создать растровое изображение с желаемым размером. Как правило, оставайтесь ниже предела openGL (обычно 2048 пикселей на наибольшей стороне)

Затем используйте Matrix для преобразования исходного растрового изображения в целевое значение.

Matrix matrix=new Matrix();
matrix.postScale(0.001f,0.001f); // whatever scale you want to use
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapSource, 0, newWidth, newHeight, matrix, true);

Обратите внимание, что если ваши изображения поступают из файлов, существуют различные механизмы для их декодирования с изменением размера, чтобы не открывать полноразмерное изображение (с проблемами памяти и производительности), см. BitmapFactory.Options

0 голосов
/ 15 января 2020

Я столкнулся с той же проблемой в моем приложении, даже в присутствии Glide и Picasso. Я решил это, указав высоту и ширину желаемого вида. Таким образом, приложение не превышает лимит памяти приложения и мобильного телефона. Вот фрагмент кода из моего приложения.

val options = RequestOptions()
    .format(DecodeFormat.PREFER_RGB_565)
    .placeholder(R.drawable.ic_placeholder)
    .error(R.drawable.ic_error)

Glide.with(this)
     .setDefaultRequestOptions(options)
     .load(campaign!!.imageURL)
     .centerInside()
     .into(object : CustomTarget<Drawable>(width, height) {
         override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
              imagePort.setImageDrawable(resource)
         }

        override fun onLoadCleared(placeholder: Drawable?) {

        }
     })

Изменения для вашего кода: я выполнил ваш код, это будет рабочая копия с использованием glide. Только не забудьте добавить зависимости глиссады в ваш файл Gradle

implementation 'com.github.bumptech.glide:glide:4.11.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

Изменения в вашей функции onActivityResult ...

protected void onActivityResult(int RC, int RQC, Intent I) {
        super.onActivityResult(RC, RQC, I);
        if (RC == 1 && RQC == RESULT_OK && I != null && I.getData() != null) {
            Uri uri = I.getData();
            RequestOptions options = new RequestOptions()
                    .format(DecodeFormat.PREFER_RGB_565)
                    .placeholder(R.drawable.ic_launcher_background)
                    .error(R.drawable.ic_launcher_background);

            Glide.with(this)
                    .setDefaultRequestOptions(options)
                    .load(uri)
                    .centerInside()
                    .into(new CustomTarget<Drawable>(1000, 500) {
                        @Override
                        public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) {
                            imageView1.setImageDrawable(resource);
                        }

                        @Override
                        public void onLoadCleared(@Nullable Drawable placeholder) {

                        }
                    });
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...