如何将位图保存在从 Internet 下载的内部存储中
Posted
技术标签:
【中文标题】如何将位图保存在从 Internet 下载的内部存储中【英文标题】:How to save bitmap on internal storage download from internet 【发布时间】:2013-11-14 12:50:22 【问题描述】:我正在使用 Asynctask 从 Internet 下载图像。
我想将此图像保存到内部存储中,稍后我想使用此图像。
我可以下载成功,但我找不到它存储的内部存储路径。
这个下载Images.java
private class DownloadImages extends AsyncTask<String,Void,Bitmap>
private Bitmap DownloadImageBitmap()
HttpURLConnection connection = null;
InputStream is = null;
try
URL get_url = new URL("http://www.medyasef.com/wp-content/themes/medyasef/images/altlogo.png");
connection = (HttpURLConnection) get_url.openConnection();
connection.setDoInput(true);
connection.setDoOutput(true);
connection.connect();
is = new BufferedInputStream(connection.getInputStream());
final Bitmap bitmap = BitmapFactory.decodeStream(is);
// ??????????
catch (MalformedURLException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
finally
connection.disconnect();
try
is.close();
catch (IOException e)
e.printStackTrace();
return null;
@Override
protected Bitmap doInBackground(String... params)
return DownloadImageBitmap();
任何帮助将不胜感激。 :)
谢谢。
【问题讨论】:
android Saving created bitmap to directory on sd card的可能重复 您已获得位图final Bitmap bitmap = BitmapFactory.decodeStream(is);
使用此位图以备将来使用。有什么大不了的?
看这个答案***.com/a/7887114/964741
【参考方案1】:
您可以像这样在内部存储中保存和加载图像: 保存:
public static void saveFile(Context context, Bitmap b, String picName)
FileOutputStream fos;
try
fos = context.openFileOutput(picName, Context.MODE_PRIVATE);
b.compress(Bitmap.CompressFormat.PNG, 100, fos);
catch (FileNotFoundException e)
Log.d(TAG, "file not found");
e.printStackTrace();
catch (IOException e)
Log.d(TAG, "io exception");
e.printStackTrace();
finally
fos.close();
加载中:
public static Bitmap loadBitmap(Context context, String picName)
Bitmap b = null;
FileInputStream fis;
try
fis = context.openFileInput(picName);
b = BitmapFactory.decodeStream(fis);
catch (FileNotFoundException e)
Log.d(TAG, "file not found");
e.printStackTrace();
catch (IOException e)
Log.d(TAG, "io exception");
e.printStackTrace();
finally
fis.close();
return b;
但是如果您想在应用程序关闭时再次找到它,则需要以某种方式保存 imageName。我会推荐一个 SQLLite 数据库,它将 imageNames 映射到数据库中的条目。
【讨论】:
您好,这个答案对我有用。但我还有一个问题。我的文件名 data/data/试试这个:
String path = Environment.getExternalStorageDirectory().toString();
OutputStream fOut = null;
String imageName = "yourImageName";
File file = new File(path, imageName);
try
fOut = new FileOutputStream(file);
if (!yourBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fOut))
Log.e("Log", "error while saving bitmap " + path + imageName);
catch (FileNotFoundException e)
// TODO Auto-generated catch block
e.printStackTrace();
【讨论】:
首先感谢您的回答,但我不想要外部存储。【参考方案3】:我在 Kotlin 上的解决方案。 (基于另一个答案)
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException
class InternalStorageProvider(var context: Context)
fun saveBitmap(bitmap: Bitmap, imageName: String)
var fileOutputStream: FileOutputStream? = null
try
fileOutputStream = context.openFileOutput(imageName, Context.MODE_PRIVATE)
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream)
catch (e: FileNotFoundException)
e.printStackTrace()
catch (e: IOException)
e.printStackTrace()
finally
fileOutputStream?.close()
fun loadBitmap(picName: String): Bitmap?
var bitmap: Bitmap? = null
var fileInputStream: FileInputStream? = null
try
fileInputStream = context.openFileInput(picName)
bitmap = BitmapFactory.decodeStream(fileInputStream)
catch (e: FileNotFoundException)
e.printStackTrace()
catch (e: IOException)
e.printStackTrace()
finally
fileInputStream?.close()
return bitmap
【讨论】:
你能解释一下你是如何初始化这个类的吗?使用InternalStorageProvider(context).saveBitmap(bitmap, filename)
调用此类时遇到问题。我做错什么了吗?
请提供一些细节。你是在Activity、Fragment还是其他类中试试下面的代码
我从片段中调用这个类。如果我将此代码放在片段中,它就可以工作。这是一个有点奇怪的问题,因为由于某种原因我无法将此类导入片段:import com.packagename... helpers.InternalStorageProvider
未解决。如果我删除上下文构造函数导入工作。
猜猜看,在片段中工作。无论如何,我稍后会对此进行探索,我只是想知道我的语法是否正常,看起来是这样。我还是 Kotlin 的新手,我正在将我的代码从 Java 重写为 Android ..【参考方案4】:
您是否考虑过使用 Glide 库(或 Picasso)来下载图片?这样您就可以抽象出 Http 连接、磁盘保存、内存和磁盘缓存、离线功能等所有低级细节。此外,如果您选择 Glide,您会在图像加载时自动获得一些整齐的淡入淡出动画。
示例(科特林)
下载到磁盘:
Glide.with(applicationContext)
.load(user.picUrl)
.downloadOnly(object : SimpleTarget<File>()
override fun onResourceReady(res: File, glideAnimation: GlideAnimation<in File>)
)
从缓存加载,如果缓存不可用则下载:
Glide.with(callingActivity.applicationContext)
.load(wallPostViewHolder.mUser!!.picUrl)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(wallPostViewHolder.vPic)
【讨论】:
【参考方案5】:当您对此进行编程并运行该应用程序时,有时需要从您的模拟器/手机中卸载该应用程序(如果您已将文件定义为文件夹,并且您更正了该文件,但在模拟器的内存中/手机还是文件夹)
【讨论】:
【参考方案6】:如果您使用的是 kotlin,请使用以下函数。你必须提供一个存储图像的路径,一个位图(转换你的图像,然后将该位图传递给这个函数),如果你想降低图像的质量,那么提供 %age 即 10%。
fun cacheToLocal(localPath: String, bitmap: Bitmap, quality: Int = 100)
val file = File(localPath)
file.createNewFile()
val ostream = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, ostream)
ostream.flush()
ostream.close()
【讨论】:
以上是关于如何将位图保存在从 Internet 下载的内部存储中的主要内容,如果未能解决你的问题,请参考以下文章
在从 Internet 下载数据期间,在 AsyncTask 的 onProgressUpdate 中显示确定的 ProgressBar