Azure 平台/Dotnet 核心上的可靠图像处理
Reliable image handling on Azure platform / Dotnet core
我在 dotnet core 下的 Azure 平台上遇到一些图像问题,我希望有人能提出明智的建议。
足够简单的前提:用户上传图像,以 base64 格式保存在数据库中(即将移动到 Azure 存储 blob,但这与此无关)。稍后,站点所有者出现并单击一个按钮将所有这些图像下载到一个 ZIP 文件中。在 .net 框架的过去,这很容易。现在我似乎正在点击一组 'yes, but' 评论。
是的,有 system.drawing.image 但您不能使用它,因为它不在 dotnet 核心中(直到最近)。
是的,您可以使用 CoreCompat,但它在 Azure 上不起作用,因为在 Web 应用程序中不支持 GDI+。
是的,即使我可以,我正在 Mac 上开发,所以据我所知它不会在本地工作。
我试过 ImageSharp 的 beta4,但不太成功。它是随机的 - 有时它有效,有时它只是抛出 OutOfMemoryException。
我试过 SkiaSharp 但结果相似;有时有效,有时会随机发出错误消息。
我在处理方面没有做任何花哨的事情,没有调整大小或任何东西。它应该是从 Convert.FromBase64String 加载文件到字节数组,创建 Zip 文件条目,最终吐出 zip 文件的情况。 ZIP 部分很好,但我需要一些可以完成图像工作的体面的东西。
这里有一些代码:
if(!string.IsNullOrEmpty(del.Headshot))
{
var output=SKImage.FromBitmap(SKBitmap.Decode(Convert.FromBase64String(del.Headshot)));
MemoryStream savedFile=new MemoryStream();
output.Encode(SKEncodedImageFormat.Jpeg, 100).SaveTo(savedFile);
string name=$"{del.FirstName} {del.LastName} - {del.Company}".Trim(Path.GetInvalidFileNameChars()) + "_Headshot.jpg";
ZipArchiveEntry entry=zip.CreateEntry(name);
using(Stream entryStream=entry.Open())
{
entryStream.Write(savedFile.ToArray(), 0, Convert.ToInt32(savedFile.Length));
}
output.Dispose();
savedFile.Dispose();
}
在我拔掉剩下的头发之前,任何人都可以给我一个可以处理图像、跨平台和在 Azure 上的库的明智建议!
谢谢
编辑:第一个答案在技术上是正确的,我不需要其他任何东西。但是,当我说我没有进行任何图像处理时,我可能有点错了。因为它都是 base64,没有任何地方存储文件名,所以我不知道它是什么类型的文件。因此,我将每一个都保存为 JPEG,以确保我始终可以输出该文件类型和扩展名。我猜用户可能会上传 JPG / PNG 甚至 GIF。
从技术上讲,您不需要任何其他成像(除非您要做的不仅仅是压缩内容)。将 base64 转换为字节数组并将其传递给 zip 文件。无需保存到磁盘即可再次读回以进行压缩。
//...
if(!string.IsNullOrEmpty(del.Headshot)) {
var imageBytes = Convert.FromBase64String(del.Headshot);
string name = $"{del.FirstName} {del.LastName} - {del.Company}".Trim(Path.GetInvalidFileNameChars()) + "_Headshot.jpg";
ZipArchiveEntry entry = zip.CreateEntry(name);
using(Stream entryStream = entry.Open()) {
entryStream.Write(imageBytes, 0, imageBytes.Length));
}
}
//...
在转换为 base64 时还对已知图像类型使用了小技巧
public static class ImagesUtility {
static IDictionary<string, string> mimeMap =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "IVBOR", "png" },
{ "/9J/4", "jpg" },
//...add others
};
/// <summary>
/// Extract image file extension from base64 string.
/// </summary>
/// <param name="base64String">base64 string.</param>
/// <returns>file extension from string.</returns>
public static string GetFileExtension(string base64String) {
var data = base64String.Substring(0, 5);
var extension = mimeMap[data.ToUpper()];
return extension;
}
}
您可以尝试根据前缀确定文件扩展名
if(!string.IsNullOrEmpty(del.Headshot)) {
var imageBytes = Convert.FromBase64String(del.Headshot);
var ext = ImagesUtility.GetFileExtension(del.Headshot) ?? "jpg";
string name = $"{del.FirstName} {del.LastName} - {del.Company}".Trim(Path.GetInvalidFileNameChars()) + $"_Headshot.{ext}";
ZipArchiveEntry entry = zip.CreateEntry(name);
using(Stream entryStream = entry.Open()) {
entryStream.Write(imageBytes, 0, imageBytes.Length));
}
}
现在理想情况下,如果您能够控制上传的图像类型,那么您还应该验证并在保存数据以及任何需要的元数据(ie 内容时执行任何图像处理输入)。这样当从存储中提取它时,您可以确信它是正确的类型和大小。这样你以后就不用担心了。
Aspose.Drawing and Aspose.Imaging 可以在 .NET Core 上处理图像和 cross-platform 运行(我是开发人员之一)。
我在 dotnet core 下的 Azure 平台上遇到一些图像问题,我希望有人能提出明智的建议。 足够简单的前提:用户上传图像,以 base64 格式保存在数据库中(即将移动到 Azure 存储 blob,但这与此无关)。稍后,站点所有者出现并单击一个按钮将所有这些图像下载到一个 ZIP 文件中。在 .net 框架的过去,这很容易。现在我似乎正在点击一组 'yes, but' 评论。
是的,有 system.drawing.image 但您不能使用它,因为它不在 dotnet 核心中(直到最近)。 是的,您可以使用 CoreCompat,但它在 Azure 上不起作用,因为在 Web 应用程序中不支持 GDI+。 是的,即使我可以,我正在 Mac 上开发,所以据我所知它不会在本地工作。
我试过 ImageSharp 的 beta4,但不太成功。它是随机的 - 有时它有效,有时它只是抛出 OutOfMemoryException。 我试过 SkiaSharp 但结果相似;有时有效,有时会随机发出错误消息。
我在处理方面没有做任何花哨的事情,没有调整大小或任何东西。它应该是从 Convert.FromBase64String 加载文件到字节数组,创建 Zip 文件条目,最终吐出 zip 文件的情况。 ZIP 部分很好,但我需要一些可以完成图像工作的体面的东西。
这里有一些代码:
if(!string.IsNullOrEmpty(del.Headshot))
{
var output=SKImage.FromBitmap(SKBitmap.Decode(Convert.FromBase64String(del.Headshot)));
MemoryStream savedFile=new MemoryStream();
output.Encode(SKEncodedImageFormat.Jpeg, 100).SaveTo(savedFile);
string name=$"{del.FirstName} {del.LastName} - {del.Company}".Trim(Path.GetInvalidFileNameChars()) + "_Headshot.jpg";
ZipArchiveEntry entry=zip.CreateEntry(name);
using(Stream entryStream=entry.Open())
{
entryStream.Write(savedFile.ToArray(), 0, Convert.ToInt32(savedFile.Length));
}
output.Dispose();
savedFile.Dispose();
}
在我拔掉剩下的头发之前,任何人都可以给我一个可以处理图像、跨平台和在 Azure 上的库的明智建议!
谢谢
编辑:第一个答案在技术上是正确的,我不需要其他任何东西。但是,当我说我没有进行任何图像处理时,我可能有点错了。因为它都是 base64,没有任何地方存储文件名,所以我不知道它是什么类型的文件。因此,我将每一个都保存为 JPEG,以确保我始终可以输出该文件类型和扩展名。我猜用户可能会上传 JPG / PNG 甚至 GIF。
从技术上讲,您不需要任何其他成像(除非您要做的不仅仅是压缩内容)。将 base64 转换为字节数组并将其传递给 zip 文件。无需保存到磁盘即可再次读回以进行压缩。
//...
if(!string.IsNullOrEmpty(del.Headshot)) {
var imageBytes = Convert.FromBase64String(del.Headshot);
string name = $"{del.FirstName} {del.LastName} - {del.Company}".Trim(Path.GetInvalidFileNameChars()) + "_Headshot.jpg";
ZipArchiveEntry entry = zip.CreateEntry(name);
using(Stream entryStream = entry.Open()) {
entryStream.Write(imageBytes, 0, imageBytes.Length));
}
}
//...
在转换为 base64 时还对已知图像类型使用了小技巧
public static class ImagesUtility {
static IDictionary<string, string> mimeMap =
new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
{ "IVBOR", "png" },
{ "/9J/4", "jpg" },
//...add others
};
/// <summary>
/// Extract image file extension from base64 string.
/// </summary>
/// <param name="base64String">base64 string.</param>
/// <returns>file extension from string.</returns>
public static string GetFileExtension(string base64String) {
var data = base64String.Substring(0, 5);
var extension = mimeMap[data.ToUpper()];
return extension;
}
}
您可以尝试根据前缀确定文件扩展名
if(!string.IsNullOrEmpty(del.Headshot)) {
var imageBytes = Convert.FromBase64String(del.Headshot);
var ext = ImagesUtility.GetFileExtension(del.Headshot) ?? "jpg";
string name = $"{del.FirstName} {del.LastName} - {del.Company}".Trim(Path.GetInvalidFileNameChars()) + $"_Headshot.{ext}";
ZipArchiveEntry entry = zip.CreateEntry(name);
using(Stream entryStream = entry.Open()) {
entryStream.Write(imageBytes, 0, imageBytes.Length));
}
}
现在理想情况下,如果您能够控制上传的图像类型,那么您还应该验证并在保存数据以及任何需要的元数据(ie 内容时执行任何图像处理输入)。这样当从存储中提取它时,您可以确信它是正确的类型和大小。这样你以后就不用担心了。
Aspose.Drawing and Aspose.Imaging 可以在 .NET Core 上处理图像和 cross-platform 运行(我是开发人员之一)。