Подтвердить что ты не робот

Загрузка Android из URL в Bitmap

У меня вопрос о загрузке изображения с веб-сайта. Код, который я использую:

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth();
int height = display.getHeight();
Bitmap bit=null;
try {
    bit = BitmapFactory.decodeStream((InputStream)new URL("http://www.mac-wallpapers.com/bulkupload/wallpapers/Apple%20Wallpapers/apple-black-logo-wallpaper.jpg").getContent());
} catch (Exception e) {}
Bitmap sc = Bitmap.createScaledBitmap(bit,width,height,true);
canvas.drawBitmap(sc,0,0,null);

Но он всегда возвращает исключение нулевого указателя, и программа вылетает из строя. URL-адрес действителен и, похоже, работает для всех остальных. Я использую 2.3.1.

4b9b3361

Ответ 1

public static Bitmap getBitmapFromURL(String src) {
    try {
        URL url = new URL(src);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.connect();
        InputStream input = connection.getInputStream();
        Bitmap myBitmap = BitmapFactory.decodeStream(input);
        return myBitmap;
    } catch (IOException e) {
        // Log exception
        return null;
    }
}

Ответ 2

Если вы используете Picasso или Glide или Universal-Image-Loader для загрузки изображения из URL.
Вы можете просто получить загруженный растр

Для Пикассо (текущая версия 2.71828)

Java-код

Picasso.get().load(imageUrl).into(new Target() {
    @Override
    public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
        // loaded bitmap is here (bitmap)
    }

    @Override
    public void onBitmapFailed(Drawable errorDrawable) { }

    @Override
    public void onPrepareLoad(Drawable placeHolderDrawable) {}
});

Код Котлина

Picasso.get().load(url).into(object : com.squareup.picasso.Target { 
    override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {
         // loaded bitmap is here (bitmap)
    }

    override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}

    override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) {}
})

Для скольжения
Проверьте, как можно использовать glide для загрузки изображения в растровое изображение?

Для Universal-Image-Loader
Java-код

imageLoader.loadImage(imageUrl, new SimpleImageLoadingListener() 
{
    @Override
    public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) 
    {
         // loaded bitmap is here (loadedImage)
    }
});

Ответ 3

Предпочитаю следующее:

Создает Bitmap из InputStream и возвращает его:

    public static  Bitmap downloadImage(String url) {
        Bitmap bitmap = null;
        InputStream stream = null;
        BitmapFactory.Options bmOptions = new BitmapFactory.Options();
        bmOptions.inSampleSize = 1;

        try {
            stream = getHttpConnection(url);
            bitmap = BitmapFactory.decodeStream(stream, null, bmOptions);
            stream.close();
        }
        catch (IOException e1) {
            e1.printStackTrace();
            System.out.println("downloadImage"+ e1.toString());
        }
        return bitmap;
    }

  // Makes HttpURLConnection and returns InputStream

 public static  InputStream getHttpConnection(String urlString)  throws IOException {

        InputStream stream = null;
        URL url = new URL(urlString);
        URLConnection connection = url.openConnection();

        try {
            HttpURLConnection httpConnection = (HttpURLConnection) connection;
            httpConnection.setRequestMethod("GET");
            httpConnection.connect();

            if (httpConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
                stream = httpConnection.getInputStream();
            }
        }
        catch (Exception ex) {
            ex.printStackTrace();
            System.out.println("downloadImage" + ex.toString());
        }
        return stream;
    }

ПОМНИТЕ:

Android включает два HTTP-клиента: HttpURLConnection и Apache HTTP Client.   Для Gingerbread и более поздней версии HttpURLConnection - лучший выбор.

     

Из Android 3.x Honeycomb или более поздней версии вы не можете выполнить Network IO в потоке пользовательского интерфейса, и это делает throws android.os.NetworkOnMainThreadException. Вы должны использовать Asynctask, как показано ниже

/**     AsyncTAsk for Image Bitmap  */
    private class AsyncGettingBitmapFromUrl extends AsyncTask<String, Void, Bitmap> {


        @Override
        protected Bitmap doInBackground(String... params) {

            System.out.println("doInBackground");

            Bitmap bitmap = null;

            bitmap = AppMethods.downloadImage(params[0]);

            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {

            System.out.println("bitmap" + bitmap);

        }
    }

Ответ 4

public Drawable loadImageFromURL(String url, String name) {
    try {
        InputStream is = (InputStream) new URL(url).getContent();
        Drawable d = Drawable.createFromStream(is, name);
        return d;
    } catch (Exception e) {
        return null;
    }
}

Ответ 5

Следуйте методу, чтобы получить url для растрового изображения в android, просто передайте ссылку этого изображения и получите растровое изображение.

public static Bitmap getBitmapFromURL(String imgUrl) {
    try {
        URL url = new URL(imgUrl);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.setDoInput(true);
        connection.connect();
        InputStream input = connection.getInputStream();
        Bitmap myBitmap = BitmapFactory.decodeStream(input);
        return myBitmap;
    } catch (IOException e) {
        // Log exception
        return null;
    }
}

Ответ 6

Пропустите свой URL-адрес изображения: Попробуйте следующее:

private Bitmap getBitmap(String url) 
    {
        File file=fileCache.getFile(url);
        Bitmap bm = decodeFile(file);
        if(bm!=null) 
            return bm;
        try {
            Bitmap bitmap=null;
            URL ImageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection)ImageUrl.openConnection();
            conn.setConnectTimeout(50000);
            conn.setReadTimeout(50000);
            conn.setInstanceFollowRedirects(true);
            InputStream is = conn.getInputStream();
            OutputStream os = new FileOutputStream(file);
            Utils.CopyStream(is, os);
            os.close();
            bitmap = decodeFile(file);
            return bitmap;
        } catch (Exception ex){
           ex.printStackTrace();
           return null;
        }
    }
    private Bitmap decodeFile(File file){
        try {
            BitmapFactory.Options opt = new BitmapFactory.Options();
            opt.inJustDecodeBounds = true;
            BitmapFactory.decodeStream(new FileInputStream(file),null,opt);
            final int REQUIRED_SIZE=70;
            int width_tmp=opt.outWidth, height_tmp=opt.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;
            }
            BitmapFactory.Options opte = new BitmapFactory.Options();
            opte.inSampleSize=scale;
            return BitmapFactory.decodeStream(new FileInputStream(file), null, opte);
        } catch (FileNotFoundException e) {}
        return null;
    }

Создать класс Utils:

public class Utils {
    public static void CopyStream(InputStream is, OutputStream os)
    {
        final int buffer_size=1024;
        try
        {
            byte[] bytes=new byte[buffer_size];
            for(;;)
            {
              int count=is.read(bytes, 0, buffer_size);
              if(count==-1)
                  break;
              os.write(bytes, 0, count);
            }
        }
        catch(Exception ex){}
    }
}

Ответ 7

Попробуйте следующее:

AQuery aq = new AQuery(getActivity());
            aq.id(view.findViewById(R.id.image)).image(imageUrl, true, true, 0,  0,
                    new BitmapAjaxCallback() {
                        @Override
                        public void callback(String url, ImageView iv, Bitmap bm, AjaxStatus status){
                            iv.setImageBitmap(bm);
                        }
                    }.header("User-Agent", "android"));

Ответ 8

Glide.with(context)
    .load("http://test.com/yourimage.jpg")  
    .asBitmap()  // переводим его в нужный формат
    .fitCenter()
    .into(new SimpleTarget<Bitmap>(100,100) {
          @Override
          public void onResourceReady(Bitmap bitmap, GlideAnimation<? super Bitmap> glideAnimation) {

           // do something with you bitmap 

                bitmap

          }
    }); 

Ответ 9

Это работает в Pie OS Используйте это

    @Override
    protected void onCreate() {
        super.onCreate();
        //setNotificationBadge();

        if (android.os.Build.VERSION.SDK_INT >= 9) {
            StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
            StrictMode.setThreadPolicy(policy);
        }

    }

        BottomNavigationView bottomNavigationView = (BottomNavigationView) findViewById(R.id.navigation);
        Menu menu = bottomNavigationView.getMenu();
        MenuItem userImage = menu.findItem(R.id.navigation_download);
        userImage.setTitle("Login");

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try {

                    URL url = new URL("https://rukminim1.flixcart.com/image/832/832/jmux18w0/mobile/b/g/n/mi-redmi-6-mzb6387in-original-imaf9z8eheryfbsu.jpeg?q=70");
                    Bitmap myBitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());

                    Log.e("keshav", "Bitmap " + myBitmap);
                    userImage.setIcon(new BitmapDrawable(getResources(), myBitmap));

                } catch (IOException e) {
                    Log.e("keshav", "Exception " + e.getMessage());
                }
            }
        });

Ответ 10

Используйте сопрограммы Kotlin для обработки потоков

Причина сбоя кода в том, что Bitmap пытается быть создана в Main Thread что недопустимо, поскольку это может привести к ошибкам Android Not Responding (ANR).

Используемые понятия

  • Котлин сопрограммы отмечает.
  • Шаблон Загрузка, Содержание, Ошибка (LCE) используется ниже. Если вы заинтересованы, вы можете узнать больше об этом в этом разговоре и видео.
  • LiveData используется для возврата данных. Я собрал свой любимый ресурс LiveData в этих заметках.
  • В бонусном коде toBitmap() является функцией расширения Kotlin, требующей добавления этой библиотеки в зависимости приложения.

Реализация

Код

1. Создайте Bitmap в другом потоке, чем Main Thread поток.

В этом примере с использованием Kotlin Coroutines функция выполняется в потоке Dispatchers.IO который предназначен для операций на базе процессора. Функция имеет префикс suspend который является синтаксисом Coroutine.

Бонус - после создания Bitmap он также сжимается в ByteArray чтобы его можно было передать через Intent описано ниже в этом полном примере.

Repository.kt

suspend fun bitmapToByteArray(url: String) = withContext(Dispatchers.IO) {
    MutableLiveData<Lce<ContentResult.ContentBitmap>>().apply {
        postValue(Lce.Loading())
        postValue(Lce.Content(ContentResult.ContentBitmap(
            ByteArrayOutputStream().apply {
                try {                     
                    BitmapFactory.decodeStream(URL(url).openConnection().apply {
                        doInput = true
                        connect()
                    }.getInputStream())
                } catch (e: IOException) {
                   postValue(Lce.Error(ContentResult.ContentBitmap(ByteArray(0), "bitmapToByteArray error or null - ${e.localizedMessage}")))
                   null
                }?.compress(CompressFormat.JPEG, BITMAP_COMPRESSION_QUALITY, this)
           }.toByteArray(), "")))
        }
    }

ViewModel.kt

//Calls bitmapToByteArray from the Repository
private fun bitmapToByteArray(url: String) = liveData {
    emitSource(switchMap(repository.bitmapToByteArray(url)) { lce ->
        when (lce) {
            is Lce.Loading -> liveData {}
            is Lce.Content -> liveData {
                emit(Event(ContentResult.ContentBitmap(lce.packet.image, lce.packet.errorMessage)))
            }
            is Lce.Error -> liveData {
                Crashlytics.log(Log.WARN, LOG_TAG,
                        "bitmapToByteArray error or null - ${lce.packet.errorMessage}")
            }
        }
    })
}

Бонус - конвертировать ByteArray обратно в Bitmap.

Utils.kt

fun ByteArray.byteArrayToBitmap(context: Context) =
    run {
        BitmapFactory.decodeByteArray(this, BITMAP_OFFSET, size).run {
            if (this != null) this
            // In case the Bitmap loaded was empty or there is an error I have a default Bitmap to return.
            else AppCompatResources.getDrawable(context, ic_coinverse_48dp)?.toBitmap()
        }
    }

Ответ 11

очень быстрый способ, этот метод работает очень быстро:

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();
            bitmap = decodeFile(f);
            return bitmap;
        } catch (Exception ex){
           ex.printStackTrace();
           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;
            BitmapFactory.decodeStream(new FileInputStream(f),null,o);

            //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;
            return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
        } catch (FileNotFoundException e) {}
        return null;
    }

Ответ 12

public static Bitmap getImgBitmapFromUri(final String url, final Activity context, final CropImageView imageView, final File file) {
    final Bitmap bitmap = null;
    AsyncTask.execute(new Runnable() {
        @Override
        public void run() {
            try {
                Utils.image = Glide.with(context)
                        .load(url).asBitmap()
                        .into(100, 100).get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
            context.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (imageView != null)
                        imageView.setImageBitmap(Utils.image);
                }
            });
        }
    });
    return Utils.image;
}

Использовать библиотеку Glide и запустить следующий код в рабочем потоке, опубликованном

Ответ 13

Пожалуйста, попробуйте следующие шаги.

1) Создайте AsyncTask в классе или адаптере (если вы хотите изменить изображение элемента списка).

public class AsyncTaskLoadImage extends AsyncTask<String, String, Bitmap> {
        private final static String TAG = "AsyncTaskLoadImage";
        private ImageView imageView;

        public AsyncTaskLoadImage(ImageView imageView) {
            this.imageView = imageView;
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            Bitmap bitmap = null;
            try {
                URL url = new URL(params[0]);
                bitmap = BitmapFactory.decodeStream((InputStream) url.getContent());
            } catch (IOException e) {
                e.printStackTrace();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return bitmap;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            try {
                int width, height;
                height = bitmap.getHeight();
                width = bitmap.getWidth();

                Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
                Canvas c = new Canvas(bmpGrayscale);
                Paint paint = new Paint();
                ColorMatrix cm = new ColorMatrix();
                cm.setSaturation(0);
                ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
                paint.setColorFilter(f);
                c.drawBitmap(bitmap, 0, 0, paint);
                imageView.setImageBitmap(bmpGrayscale);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

2) Вызовите AsyncTask из вашей деятельности, фрагмента или адаптера (внутри onBindViewHolder).

2.a) Для адаптера:

    String src = current.getProductImage();
    new AsyncTaskLoadImage(holder.icon).execute(src);

2.b) По активности и фрагменту:

**Activity:**
  ImageView imagview= (ImageView) findViewById(R.Id.imageview);
  String src = (your image string);
  new AsyncTaskLoadImage(imagview).execute(src);

**Fragment:**
  ImageView imagview= (ImageView)view.findViewById(R.Id.imageview);
  String src = (your image string);
  new AsyncTaskLoadImage(imagview).execute(src);

3) Пожалуйста, запустите приложение и проверьте изображение.

Удачного кодирования.... :)

Ответ 14

Если вы используете Picasso для изображений, вы можете попробовать метод ниже!

public static Bitmap getImageBitmapFromURL(Context context, String imageUrl){
    Bitmap imageBitmap = null;
    try {
      imageBitmap = new AsyncTask<Void, Void, Bitmap>() {
        @Override
        protected Bitmap doInBackground(Void... params) {
          try {
            int targetHeight = 200;
            int targetWidth = 200;

            return Picasso.with(context).load(String.valueOf(imageUrl))
              //.resize(targetWidth, targetHeight)
              .placeholder(R.drawable.raw_image)
              .error(R.drawable.raw_error_image)
              .get();
          } catch (IOException e) {
            e.printStackTrace();
          }
          return null;
        }
      }.execute().get();
    } catch (InterruptedException e) {
      e.printStackTrace();
    } 
  return imageBitmap;
  }

Ответ 15

если вы используете Glide и Kotlin,

Glide.with(this)
            .asBitmap()
            .load("https://...")
            .addListener(object : RequestListener<Bitmap> {
                override fun onLoadFailed(
                    e: GlideException?,
                    model: Any?,
                    target: Target<Bitmap>?,
                    isFirstResource: Boolean
                ): Boolean {
                    Toast.makeText([email protected], "failed: " + e?.printStackTrace(), Toast.LENGTH_SHORT).show()
                    return false
                }

                override fun onResourceReady(
                    resource: Bitmap?,
                    model: Any?,
                    target: Target<Bitmap>?,
                    dataSource: DataSource?,
                    isFirstResource: Boolean
                ): Boolean {
                    //image is ready, you can get bitmap here
                    var bitmap = resource
                    return false
                }

            })
            .into(imageView)

Ответ 16

fun getBitmap(url : String?) : Bitmap? {
    var bmp : Bitmap ? = null
    Picasso.get().load(url).into(object : com.squareup.picasso.Target {
        override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {
            bmp =  bitmap
        }

        override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}

        override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) {}
    })
    return bmp
}

Попробуйте это с Пикассо

Ответ 17

  private class AsyncTaskRunner extends AsyncTask<String, String, String> {
    String Imageurl;

    public AsyncTaskRunner(String Imageurl) {
        this.Imageurl = Imageurl;
    }

    @Override
    protected String doInBackground(String... strings) {

        try {

            URL url = new URL(Imageurl);
            thumbnail_r = BitmapFactory.decodeStream(url.openConnection().getInputStream());


        } catch (IOException e) {
        }
        return null;
    }

    @Override
    protected void onPostExecute(String s) {
        super.onPostExecute(s);


        imgDummy.setImageBitmap(thumbnail_r);
        UtilityMethods.tuchOn(relProgress);
    }
}

Вызовите asynctask как:

 AsyncTaskRunner asyncTaskRunner = new AsyncTaskRunner(uploadsModel.getImages());
        asyncTaskRunner.execute();

Ответ 18

Если вы загружаете URL из растрового изображения без использования AsyncTask, напишите две строки после setContentView (R.layout.abc);

StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

try {
    URL url = new URL("http://....");
    Bitmap image = BitmapFactory.decodeStream(url.openConnection().getInputStream());
} catch(IOException e) {
    System.out.println(e);
}