Перед прочтением ответа прочитайте маркированные пункты:
Действительно полезное преобразование, должно возвращать JPEG-кодированное изображение, которое эквивалентно содержанию файла Jpeg, который не является данными пикселей.
Когда вы получите массив данных пикселей изображения Jpeg, у вас не будет преимуществ от изображения Jpeg. Это больше не изображение в формате Jpeg, это массив данных пикселей, который можно использовать для создания BitMap
.
Чтобы лучше понять суть, например, для белого изображения JPEG с разрешением 10K данные в пикселях будут 2 МБ!
В этом ответе я поделился несколькими методами, которые действительно полезны, и я показал, как их можно объединить, чтобы получить то, что вы хотеть. (Хотя я не вижу никакой выгоды в преобразовании, которое вы пытаетесь сделать.)
Это очень полезные части, которые вы можете собрать вместе, чтобы решить головоломку. :
- ImageData : В дополнение к
byte[]
пикселей изображения необходимо знать о ширине, высоте и формате пикселей изображения. Затем вы можете описать изображение и создать Image
из этих данных. Без всей этой информации byte[]
само по себе не имеет смысла. - GetImageDataFromImage : получает данные изображения (ширина, высота, формат пикселя, данные пикселя) из
Image
- CreateImageFromImageData : Создает
Image
из данных изображения - ConvertImageToJpegImage : Преобразует
Image
в Jpeg Image
- ByteArrayToBase64 : Преобразует
byte[]
в строку Base64.
Затем, получив эти кусочки, вы можете достичь того, что вы хотите.
Предполагая, что у вас есть byte[]
пикселей, ширина, высота и формат пикселей ваших данных, это это то, что вам нужно:
// A 2x2 image having 24 bit RGB pixel format, all pixels are #FF0000 (Red)
var imageData = new ImageData()
{
Width = 2,
Height = 2,
PixelFormat = PixelFormat.Format24bppRgb,
PixelData = new byte[] {
0x0, 0x0, 0xFF, 0x0, 0x0, 0xFF,
0xF, 0x0, 0xFF, 0x0, 0x0, 0xFF
}
};
var image = CreateImageFromImageData(imageData);
var jpeg = ConvertImageToJpegImage(image);
var jpegImageData = GetImageDataFromImage(jpeg);
var jpegPixelsBase64 = ByteArrayToBase64(jpegImageData.PixelData);
В результате получается AAD+AAD+AAD+AAD+
, который фактически является изображением, имеющим #FE0000
цвет!
Примечание: I не располагать изображения, чтобы сохранить его четким, в действии, вы должны располагать изображения и JPEG.
ImageData
Необходимая информация об изображении, в том числе ширина, высота, формат пикселей и массив данных пикселей:
public class ImageData
{
public int Width { get; set; }
public int Height { get; set; }
public PixelFormat PixelFormat { get; set; }
public byte[] PixelData { get; set; }
}
GetImageDataFromImage
Получает данные изображения из изображения.
ImageData GetImageDataFromImage(Image image)
{
using (var bitmap = new Bitmap(image.Width, image.Height, image.PixelFormat))
{
using (var g = Graphics.FromImage(bitmap))
g.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height));
var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly, bitmap.PixelFormat);
var rowLength = image.Width * Image.GetPixelFormatSize(image.PixelFormat) / 8;
var bytes = new byte[image.Height * rowLength];
var ptr = data.Scan0;
for (var i = 0; i < image.Height; i++)
{
Marshal.Copy(ptr, bytes, i * rowLength, rowLength);
ptr += data.Stride;
}
bitmap.UnlockBits(data);
return new ImageData
{
Width = bitmap.Width,
Height = bitmap.Height,
PixelFormat = bitmap.PixelFormat,
PixelData = bytes
};
}
}
Мы используем LockBits
для получения или установки байтового массива изображения.
CreateImageFromImageData
Создает изображение из данных изображения:
Image CreateImageFromImageData(ImageData imageData)
{
var bitmap = new Bitmap(imageData.Width, imageData.Height, imageData.PixelFormat);
var data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadWrite, bitmap.PixelFormat);
var rowLength = imageData.Width * Image.GetPixelFormatSize(imageData.PixelFormat) / 8;
var bytes = new byte[imageData.Height * rowLength];
var ptr = data.Scan0;
for (var i = 0; i < imageData.Height; i++)
{
Marshal.Copy(imageData.PixelData, i * rowLength, ptr, rowLength);
ptr += data.Stride;
}
bitmap.UnlockBits(data);
return bitmap;
}
Мы используем LockBits
для получения или установки байтового массива изображения.
ConvertImageToJpegImage
Преобразует изображение в формат JPEG:
public Image ConvertImageToJpegImage(Image img)
{
using (var stream = new MemoryStream())
{
img.Save(stream, ImageFormat.Jpeg);
var bytes = stream.ToArray();
return (Image)new ImageConverter().ConvertFrom(bytes);
}
}
Если вам важен уровень сжатия, используйте кодировщик JPEG .
ByteArrayToBase64
Преобразование из byte[]
в Base64String
и является простым, но для лучшей читаемости ответа и кода:
public string ByteArrayToBase64(byte[] bytes)
{
return Convert.ToBase64String(bytes);
}