You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Xamarin.Android中保存、获取并使用合并生成的Bitmap?

嘿,你已经搞定了Bitmap合并的第一步,先把你没写完的合并代码补全(应该是用Canvas把第二张图绘制到第一张上吧?):

string OnePath = "backgroundimage"; 
string TwoPath = "objectimage"; 
var OneImage = BitmapFactory.DecodeResource(Resources, Resources.GetIdentifier(OnePath, "drawable", PackageName)); 
var TwoImage = BitmapFactory.DecodeResource(Resources, Resources.GetIdentifier(TwoPath, "mipmap", PackageName)); 

// 复制背景图并开启可编辑模式
Bitmap bitmap = OneImage.Copy(Bitmap.Config.Argb8888, true); 
// 创建Canvas来绘制第二张图
Canvas canvas = new Canvas(bitmap);
// 把第二张图绘制到背景图的左上角,你可以调整坐标或大小,比如用Rect来缩放
canvas.DrawBitmap(TwoImage, 0, 0, null);

// 记得用完的Bitmap要回收,避免内存泄漏
OneImage.Recycle();
TwoImage.Recycle();

接下来咱们一步步实现存储、保存、查看和使用这些功能:

一、保存Bitmap到本地

根据你的需求,分两种存储场景:

1. 保存到应用内部存储(仅本应用可访问,无需额外权限)

这种方式适合不需要用户在系统相册看到的图片:

private void SaveBitmapToInternalStorage(Bitmap bitmap, string fileName)
{
    try
    {
        // 打开应用内部的输出流
        using (var stream = OpenFileOutput(fileName, FileCreationMode.Private))
        {
            // 压缩Bitmap为PNG格式(也可以用JPEG,第二个参数是质量0-100)
            bitmap.Compress(Bitmap.CompressFormat.Png, 100, stream);
        }
        Toast.MakeText(this, "保存成功到内部存储", ToastLength.Short).Show();
    }
    catch (Exception ex)
    {
        Toast.MakeText(this, $"保存失败:{ex.Message}", ToastLength.Short).Show();
    }
}

调用示例:SaveBitmapToInternalStorage(bitmap, "merged_image.png");

2. 保存到外部存储(系统相册可查看,需处理权限)

Android 10及以上推荐用MediaStore来保存,避免权限问题:

private async Task SaveBitmapToGallery(Bitmap bitmap)
{
    try
    {
        // 准备图片的元数据
        var values = new ContentValues();
        values.Put(MediaStore.Images.Media.Columns.DisplayName, "merged_image_" + DateTime.Now.Ticks);
        values.Put(MediaStore.Images.Media.Columns.MimeType, "image/png");
        values.Put(MediaStore.Images.Media.Columns.RelativePath, Environment.DirectoryPictures + "/MyAppImages");

        // 获取ContentResolver并插入元数据
        var uri = ContentResolver.Insert(MediaStore.Images.Media.ExternalContentUri, values);
        if (uri == null) throw new Exception("无法获取存储URI");

        // 写入Bitmap数据
        using (var stream = ContentResolver.OpenOutputStream(uri))
        {
            bitmap.Compress(Bitmap.CompressFormat.Png, 100, stream);
        }

        // 通知系统相册更新
        MediaScannerConnection.ScanFile(this, new string[] { uri.Path }, null, null);
        Toast.MakeText(this, "已保存到相册", ToastLength.Short).Show();
    }
    catch (Exception ex)
    {
        Toast.MakeText(this, $"保存到相册失败:{ex.Message}", ToastLength.Short).Show();
    }
}

调用示例:await SaveBitmapToGallery(bitmap);(注意在异步方法中调用)

二、查看已保存的Bitmap

1. 从内部存储读取

private Bitmap LoadBitmapFromInternalStorage(string fileName)
{
    try
    {
        using (var stream = OpenFileInput(fileName))
        {
            return BitmapFactory.DecodeStream(stream);
        }
    }
    catch (Exception ex)
    {
        Toast.MakeText(this, $"读取失败:{ex.Message}", ToastLength.Short).Show();
        return null;
    }
}

2. 从外部存储/相册读取

如果是自己保存的图片,可以通过URI直接读取,这里给个通用的通过URI读取的方法:

private Bitmap LoadBitmapFromUri(Uri uri)
{
    try
    {
        using (var stream = ContentResolver.OpenInputStream(uri))
        {
            return BitmapFactory.DecodeStream(stream);
        }
    }
    catch (Exception ex)
    {
        Toast.MakeText(this, $"读取失败:{ex.Message}", ToastLength.Short).Show();
        return null;
    }
}
三、在应用中使用已保存的Bitmap

最常见的就是显示到ImageView:

// 从内部存储读取并显示
var savedBitmap = LoadBitmapFromInternalStorage("merged_image.png");
if (savedBitmap != null)
{
    imageView.SetImageBitmap(savedBitmap);
}

// 或者直接用合并后的Bitmap显示
imageView.SetImageBitmap(bitmap);

也可以把Bitmap转换成Drawable作为控件背景:

Drawable drawable = new BitmapDrawable(Resources, bitmap);
button.SetBackground(drawable);
注意事项
  • 内存管理:Bitmap很占内存,用完记得调用bitmap.Recycle();,并设置bitmap = null;,尤其是在页面销毁时,避免内存泄漏。
  • 权限处理:如果是Android 9及以下保存到外部存储,需要在Manifest中添加WRITE_EXTERNAL_STORAGE权限,并在运行时申请;Android 10+用MediaStore无需这个权限,但如果要访问其他应用的文件,需要额外权限。
  • 压缩优化:保存时可以根据需求选择JPEG格式(压缩率更高),调整压缩质量参数,避免图片过大。

内容的提问来源于stack exchange,提问作者Carlos Rodrigez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:41:14