如何在c#中编码base64字符串时减少内存使用
本文关键字:内存 字符串 base64 编码 | 更新日期: 2023-09-27 17:55:01
我使用以下代码从位于我的计算机系统上的文件中检索位图:
Bitmap shellThumb = sf.Thumbnail.ExtraLargeBitmap;
其中sf是一个ShellFile。
然后使用以下命令将位图转换为base64:
public static string ToBase64String(this Bitmap bmp, ImageFormat imageFormat)
{
string base64String = string.Empty;
MemoryStream memoryStream = new MemoryStream();
bmp.Save(memoryStream, imageFormat);
memoryStream.Position = 0;
byte[] byteBuffer = memoryStream.ToArray();
memoryStream.Close();
base64String = Convert.ToBase64String(byteBuffer);
byteBuffer = null;
return base64String;
}
然后使用下面的代码调用这个方法:
string base64ImageAndTag = shellThumb.ToBase64String(ImageFormat.Png);
然后我使用JSON。Net将此字符串以及文件的其他属性写入JSON文件以供另一个项目使用-没有JSON的替代方案,必须使用它。
string json = JsonConvert.SerializeObject(files.ToArray(), Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
其中files为List。
我必须为指定文件夹中的每个文件读取缩略图。
从读取文件中,我得到一个OutOfMemory异常,转换是在写入JSON文件时导致这种情况的原因。
是否有一种方法来更好地编码位图,以避免异常?我已经为这个问题寻找了解决方案,但我不确定如何/在哪里应用任何可能的解决方案来实现这个工作。
多谢! !
减少内存占用的一种方法是一次序列化一个对象并将它们流式传输到输出中,而不是尝试预先在内存中生成所有对象(及其Base64字符串)。您将在Json中使用JsonSerializer
和JsonTextWriter
类。Net将图像数据一次流式传输一个。下面是一个比较两种序列化方式的简短示例。您可能会将指向输出文件的StringWriter
替换为StreamWriter
。在GenerateImageFile
内部,您将调用ToBase64String
方法。
class ImageFile
{
public string Name { get; set; }
public string Base64Image { get; set; }
}
class Program
{
static void Main(string[] args)
{
var files = new[] { "test.bmp", "test2.bmp" };
// generate all the objects and then serialize.
var imageFiles = files.Select(GenerateImageFile);
var serialized = JsonConvert.SerializeObject(imageFiles.ToArray(), Formatting.Indented, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
Console.WriteLine(serialized);
// generate objects one at a time.
// use JsonSerialzer/JsonTextWriter to "stream" the objects
var s = JsonSerializer.Create(new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore });
var strWriter = new StringWriter();
using (var writer = new JsonTextWriter(strWriter) { Formatting = Formatting.Indented })
{
writer.WriteStartArray();
foreach(var file in files)
{
var imageFile = GenerateImageFile(file);
s.Serialize(writer, imageFile);
}
writer.WriteEndArray();
}
Console.WriteLine(strWriter.GetStringBuilder());
}
private static ImageFile GenerateImageFile(string fileName)
{
return new ImageFile() { Name = fileName, Base64Image = fileName + fileName };
}
}
您可能希望压缩它。如果您想保留位图格式,您可以使用gzip(或任何其他更合适的压缩器)压缩图像。这也将是无损压缩,你不会失去任何质量。
如果你可以将其转换为jpeg,那可能会给你更高的压缩率。但是要小心,这种压缩会导致质量损失。