Android从URL加载到Bitmap

时间:2012-01-24 19:37:29

标签: java android 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。

19 个答案:

答案 0 :(得分:160)

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;
    }
}

答案 1 :(得分:18)

如果您使用PicassoGlideUniversal-Image-Loader从网址加载图片。
您可以通过

简单地获取加载的位图

毕加索(当前版本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) {}
});

Kotlin代码

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?) {}
})

For Glide
查看How does one use glide to download an image into a bitmap?

适用于Universal-Image-Loader
Java代码

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

答案 2 :(得分:9)

我更喜欢这些:

从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客户端。     对于Gingerbread及以后, HttpURLConnection 是最佳选择。

         

从Android 3.x Honeycomb或更高版本,您无法在 UI线程上执行网络IO ,并执行此操作会抛出 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);

        }
    }

答案 3 :(得分:6)

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;
    }
}

答案 4 :(得分:3)

按照方法在android中获取url到bitmap只需传递此图像的链接并获取位图。

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;
    }
}

答案 5 :(得分:2)

此方法将使用kotlin coroutine来解决问题,因此它不会阻塞UI主线程,并会返回调整大小的圆形位图图像(如个人资料图像)


import { graphql } from "gatsby"

export const query = graphql`
  {
    allAirtable(sort: {order: ASC, fields: id}, limit: 100) {
      nodes {
        id
        data {
          Name
          Area
          Year
        }
      }
    }
  }
 ` 

let startIndex = 0;
let endIndex = 10;

const IndexPage = ({ data }) => {

  return(
  <div>
    <h1>Item list</h1>
    <p>Page count: {data.allAirtable.pageInfo.pageCount}</p>
    <ul>
      {data.allAirtable.nodes.slice([startIndex], [endIndex]).map(node => (

        <li key={node.id}>
          {node.data.Name} <br />
          {node.data.Area} <br />
          {node.data.Year} <br />
        </li>

      ))}
    </ul>
    <button>More</button>
  </div>
 )}

 export default IndexPage

答案 6 :(得分:2)

传递您的图片网址:   试试这个:

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;
    }

创建类实用程序:

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 :(得分:1)

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

          }
    }); 

答案 8 :(得分:1)

使用Kotlin协程处理线程

代码崩溃的原因是因为试图在Bitmap上创建Main Thread,这是不允许的,因为这可能会导致 Android无响应(ANR)错误。

使用的概念

  • Kotlin协程 notes
  • 加载,内容,错误(LCE)模式在下面使用。如果有兴趣,可以在this talk and video中进一步了解。
  • LiveData 用于返回数据。我已经在these notes中编译了我最喜欢的 LiveData 资源。
  • 奖励代码中,toBitmap()Kotlin extension function,要求将该库添加到应用程序依赖项中。

实施

代码

1。在Bitmap之外的其他线程中创建Main Thread

在此示例中,使用 Kotlin Coroutines ,该函数在Dispatchers.IO线程中执行,该线程用于基于CPU的操作。该函数的前缀为suspend,这是协程语法。

奖金-创建Bitmap后,它也被压缩为ByteArray,因此可以通过稍后在{{ 3}}。

Repository.kt

Intent

ViewModel.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(), "")))
        }
    }

奖金-将//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

Utils.kt

Bitmap

答案 9 :(得分:1)

试试这个:

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"));

答案 10 :(得分:0)

非常快,这种方法非常快:

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;
    }

答案 11 :(得分:0)

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库并在工作线程中运行以下代码

答案 12 :(得分:0)

请尝试以下步骤。

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)从您的活动,片段或适配器(在onBindViewHolder中)调用AsyncTask。

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)请运行应用程序并检查图像。

快乐的编码.... :)

答案 13 :(得分:0)

如果您使用Picasso for Images,可以尝试以下方法!

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;
  }

答案 14 :(得分:0)

如果您使用的是Glide科特林

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(this@MainActivity, "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)

答案 15 :(得分:0)

它可以在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());
                }
            }
        });

答案 16 :(得分:0)

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 :(得分:0)

  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 :(得分:-1)

如果在不使用AsyncTask的情况下从位图加载URL,请在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);
}