Android 如何将图像保存到内部存储器,然后在另一个活动中显示?
我在Xamarin.Android工作。我有两个活动需要显示相同的图像。在第一个屏幕上,我从一个web URL下载并显示它,但我不想在第二个屏幕上做同样的事情。当它在第一个屏幕上下载时,我想将它保存到内部存储器中,然后从那里简单地检索它以在第二个活动中显示。我该怎么做 以下是我在第一个活动中使用的代码:Android 如何将图像保存到内部存储器,然后在另一个活动中显示?,android,file-io,xamarin.android,bitmapimage,Android,File Io,Xamarin.android,Bitmapimage,我在Xamarin.Android工作。我有两个活动需要显示相同的图像。在第一个屏幕上,我从一个web URL下载并显示它,但我不想在第二个屏幕上做同样的事情。当它在第一个屏幕上下载时,我想将它保存到内部存储器中,然后从那里简单地检索它以在第二个活动中显示。我该怎么做 以下是我在第一个活动中使用的代码: protected override void OnCreate (Bundle bundle) { base.OnCreate (bundle); this.SetConte
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
this.SetContentView (Resource.Layout.Main);
String uriString = this.GetUriString();
WebClient web = new WebClient ();
web.DownloadDataCompleted += new DownloadDataCompletedEventHandler(web_DownloadDataCompleted);
web.DownloadDataAsync (new Uri(uriString));
}
void web_DownloadDataCompleted(object sender, DownloadDataCompletedEventArgs e)
{
if (e.Error != null)
{
RunOnUiThread(() =>
Toast.MakeText(this, e.Error.Message, ToastLength.Short).Show());
}
else
{
Bitmap bm = BitmapFactory.DecodeByteArray(e.Result, 0, e.Result.Length);
// THIS IS WHERE I NEED TO SAVE THE IMAGE IN INTERNAL STORAGE //
RunOnUiThread(() =>
{
ProgressBar pb = this.FindViewById<ProgressBar> (Resource.Id.custLogoProgressBar);
pb.Visibility = ViewStates.Gone;
ImageView imgCustLogo = FindViewById<ImageView>(Resource.Id.imgCustLogo);
imgCustLogo.SetImageBitmap(bm);
});
}
}
但是,代码没有编译,我在调用bm.Compress()
时遇到了一个异常。它说:
Error CS1503: Argument 3: cannot convert from 'Java.IO.FileOutputStream' to 'System.IO.Stream'
位图的压缩方法将对象
OutputStream
作为第三个参数,您要传递的是FileOutputStream
(从OutputStream驱动)。您可以尝试向它传递一个OutputStream
对象,看看这是否解决了问题。好的,我就是这样让它工作的:
Bitmap bm = BitmapFactory.DecodeByteArray(e.Result, 0, e.Result.Length);
ContextWrapper cw = new ContextWrapper(this.ApplicationContext);
File directory = cw.GetDir("imgDir", FileCreationMode.Private);
File myPath = new File(directory, "test.png");
try
{
using (var os = new System.IO.FileStream(myPath.AbsolutePath, System.IO.FileMode.Create))
{
bm.Compress(Bitmap.CompressFormat.Png, 100, os);
}
}
catch (Exception ex)
{
System.Console.Write(ex.Message);
}
我认为这就是你来回转换的方式:
using (var stream = new Java.Net.URL(uriString).OpenConnection().InputStream)
{
bitmap = await BitmapFactory.DecodeStreamAsync(stream);
}
using (var stream = new Java.Net.URL(myPath.Path).OpenConnection().OutputStream)
{
await bitmap.CompressAsync(Bitmap.CompressFormat.Png, 80, stream);
}
如果您想将其保存到内部存储器,但它不会显示在gallery中
public static void SaveBitmapToInternalStorage(this Context context, Bitmap bitmap, string filename, string directory)
{
//can change directory as per need
if (directory != null || directory != "") directory = "/" + directory;
var imagesDir = context.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures+ directory);
if (!imagesDir.Exists()) imagesDir.Mkdirs();
var jFile = new Java.IO.File(imagesDir, filename);
var filePath = jFile.AbsoluteFile.ToString();
System.IO.FileStream output = null;
using (output = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
{
bitmap.Compress(Bitmap.CompressFormat.Jpeg, 90, output);
}
output.Close();
}
和检索保存的图像
注意:为了检索相同的文件,文件名和目录应该相同
public static Drawable GetDrawableFromInternalStorage(this Context context, string fileName, string directory)
{
//return drawable for imagename from internal storage
if (directory != null || directory != "") directory = "/" + directory;
var imagesDir = context.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures + directory);
if (!imagesDir.Exists()) return null;
var jFile = new Java.IO.File(imagesDir, fileName);
if (jFile.Exists())
{
var img = Drawable.CreateFromPath(jFile.ToString());
return img;
}
return null;
}
并将图像保存到gallery
public static bool SaveImageToGallery(this Context context, Bitmap bmp, string directory)
{
// First save the picture
string storePath = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + File.Separator + directory;
File imgDir = new File(storePath);
if (!imgDir.Exists()) imgDir.Mkdir();
string fileName = System.DateTime.Today.ToLongDateString() + ".jpg";
File file = new File(imgDir, fileName);
try
{
var uri = Android.Net.Uri.FromFile(file);
var os = context.ContentResolver.OpenOutputStream(uri);
//Compress and save pictures by io stream
bool isSuccess = bmp.Compress(Bitmap.CompressFormat.Jpeg, 60, os);
os.Flush();
os.Close();
//Update the database by sending broadcast notifications after saving pictures
context.SendBroadcast(new Intent(Intent.ActionMediaScannerScanFile, uri));
return isSuccess;
}
catch (IOException e) { }
return false;
}
如果要创建唯一的文件名以保存到gallery,则
File file = File.CreateTempFile(
"Img_", /* prefix */
".jpg", /* suffix */
imgDir /* directory */);
OutputStream
实际上是Java.IO.OutputStream
,因此我仍然得到错误:无法从Java.IO.OutputStream转换为System.IO.Stream
我想知道是否有人可以从通用角度回答这个问题?假设我已经创建了一个图像对象,该对象是从URI处的任意文件加载的(例如,可以是JPG、PNG等)。如何将其保存到PCL项目中的本地文件系统?我想为了简化事情,我很乐意将文件保存为常量文件类型,例如,无论原始源格式如何,始终保存为PNG。
File file = File.CreateTempFile(
"Img_", /* prefix */
".jpg", /* suffix */
imgDir /* directory */);