C# - 无论我尝试什么,Base64 字节数组到图像都会失败
本文关键字:数组 字节数 字节 图像 失败 Base64 什么 | 更新日期: 2024-08-02 00:12:01
我在从base64编码的字节数组在C#中创建图像/位图对象时遇到问题。
这是我正在处理的内容:
我有一个用户可以裁剪图像的前端。当用户通过input[type=file]
选择图像时,我的javascript代码使用HTML5的FileReader将DataUrl
(base64字符串(保存到hidden field
,该与裁剪坐标和尺寸以及该form
中的所有其他内容一起发布。
本质:
base64 数据,如果您想测试自己:
http://kristianbak.com/test_image.txt
- base64 字符串将发布到操作,并作为参数接收
imageData
- 该操作将字符串转换为 base64 字节数组,如下所示:
-
byte[] imageBytes = Convert.FromBase64String(imageData.EncodeTo64());
编码到64扩展方法:
public static string EncodeTo64(this String toEncode)
{
var toEncodeAsBytes = Encoding.ASCII.GetBytes(toEncode);
var returnValue = Convert.ToBase64String(toEncodeAsBytes);
return returnValue;
}
将 base64 字符串转换为字节数组后,我使用MemoryStream
将字节读入内存:
using (var imageStream = new MemoryStream(imageBytes, false))
{
Image image = Image.FromStream(imageStream); //ArgumentException: Parameter is not valid.
}
我还尝试了以下变体:
一(
using (var imageStream = new MemoryStream(imageBytes))
{
Bitmap image = new Bitmap(imageStream); //ArgumentException: Parameter is not valid.
}
b(
using (var imageStream = new MemoryStream(imageBytes))
{
imageStream.Position = 0;
Image image = Image.FromStream(imageStream); //ArgumentException: Parameter is not valid.
}
c(
TypeConverter typeConverter = TypeDescriptor.GetConverter(typeof(Bitmap));
Bitmap image = (Bitmap)typeConverter.ConvertFrom(imageBytes);
d(
使用此方法:
private Bitmap GetBitmap(byte[] buf)
{
Int16 width = BitConverter.ToInt16(buf, 18);
Int16 height = BitConverter.ToInt16(buf, 22);
Bitmap bitmap = new Bitmap(width, height); //ArgumentException: Parameter is not valid.
int imageSize = width * height * 4;
int headerSize = BitConverter.ToInt16(buf, 10);
System.Diagnostics.Debug.Assert(imageSize == buf.Length - headerSize);
int offset = headerSize;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
bitmap.SetPixel(x, height - y - 1, Color.FromArgb(buf[offset + 3], buf[offset], buf[offset + 1], buf[offset + 2]));
offset += 4;
}
}
return bitmap;
}
结论:
我觉得还有别的问题,希望你能回答这个问题。
编辑:
前端代码示例:
<script>
$(function() {
var reader = new window.FileReader();
function readImage(file, callBack) {
reader.onload = function (e) {
var image = new Image();
image.onload = function (imageEvt) {
if (typeof callBack == "function") {
callBack(e.target.result);
}
};
image.src = e.target.result;
};
reader.readAsDataURL(file);
}
$j('#file').change(function (e) {
var file = e.target.files[0];
readImage(file, function(imageData) {
$('#imageData').val(imageData);
});
});
});
</script>
@using (Html.BeginForm("UploadImage", "Images", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
@Html.ValidationSummary(true)
<input name="PostedImage.ImageData" type="hidden" id="imageData" value="" />
@* REST OF THE HTML CODE HERE *@
<p>Choose an image:</p>
<input type="file" name="file" id="file" />
<input type="submit" value="Upload" />
}
控制器/操作示例:
[HttpPost]
public ActionResult Opret(PostedImage postedImage)
{
String imageData = PostedImage.ImageData;
byte[] imageBytes = Convert.FromBase64String(imageData.EncodeTo64());
using (var imageStream = new MemoryStream(imageBytes, false))
{
Image image = Image.FromStream(imageStream);
}
}
我认为您的问题是您正在获取发布到控制器的 base64 字符串,将其视为 ASCII,然后再次将其转换为 base64。
我认为您需要更改此行
byte[] imageBytes = Convert.FromBase64String(imageData.EncodeTo64());
自
byte[] imageBytes = Convert.FromBase64String(imageData);
从那里你的字节应该是正确的,你应该能够创建你的图像
--编辑--
我获取了您在文本文档中提供的示例数据,并在将其加载到位图之前对其进行了解析。我能够将图像保存到我的硬盘上,并受到斯巴达人的欢迎(绿色环保!!
尝试一下这段代码,看看会发生什么。
请注意,图像数据正是 http://kristianbak.com/test_image.txt 上公开的内容。我会提供初始化,但这是一个相当大的字符串,可能会破坏事情。
string imageDataParsed = imageData.Substring( imageData.IndexOf( ',' ) + 1 );
byte[] imageBytes = Convert.FromBase64String( imageDataParsed );
using ( var imageStream = new MemoryStream( imageBytes, false ) )
{
Bitmap image = new Bitmap( imageStream );
}