I have converted image byte array into hexastring using following snippet:
public static string ByteArrayToHexString(byte[] byteArray)
{
if (byteArray == null)
return string.Empty;
try
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < byteArray.Length; i++)
{
sb.Append(byteArray[i].ToString("X2"));
}
return sb.ToString();
}
catch
{
throw;
}
}
While converting back hexastring into WriteableBitmap using following code getting error:
public static WriteableBitmap GetImage(byte[] rawImageBytes)
{
WriteableBitmap image;
using (MemoryStream ms = new MemoryStream(rawImageBytes))
{
//create decoder from MemoryStream
BitmapDecoder decoder = BitmapDecoder.Create(ms,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.OnLoad);
//create new bitmap that is detached from the MemoryStream
image = new WriteableBitmap(decoder.Frames[0]);
image.Freeze();
return image;
}
}
error
Related
ESRI Symbology library is slow and sometimes take longer time than expected.
I wish to serialize a selected range of ImageSource to a cache, string in the memory or file.
I have searched the web but not much on ImageSource.
An interesting thing I have found is "ImageSourceValueSerializer".
Being a 3 months old baby in WPF, I am not so sure how to go about this.
here's how I got the ImageSource:
MultilayerPointSymbol multiLayerSym = await result.GetSymbolAsync() as MultilayerPointSymbol;
RuntimeImage swatch = await multiLayerSym.CreateSwatchAsync();
ImageSource symbolImage = await swatch.ToImageSourceAsync();
Tested Clemen's, the routine:
MultilayerPointSymbol multiLayerSym = await result.GetSymbolAsync() as MultilayerPointSymbol;
RuntimeImage swatch = await multiLayerSym.CreateSwatchAsync();
ImageSource symbolImage = await swatch.ToImageSourceAsync();
byte[] b = ImageSourceBinary(symbolImage);
ImageSource test = BinaryImageSource(b);
In the class:
private byte[] ImageSourceBinary(ImageSource imageSrc)
{
if (imageSrc is BitmapSource bitmapSource)
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
using (MemoryStream stream = new MemoryStream())
{
encoder.Save(stream);
return stream.ToArray();
}
}
return null;
}
private ImageSource BinaryImageSource(byte[] bytes)
{
using (MemoryStream stream = new MemoryStream(bytes))
{
PngBitmapDecoder decoder = new PngBitmapDecoder(stream, BitmapCreateOptions.IgnoreImageCache, BitmapCacheOption.Default);
BitmapFrame bf = decoder.Frames[0];
if (bf is ImageSource imagesource)
return imagesource;
return null;
}
}
The outcome, no image! :(
Check if the ImageSource is a BitmapSource and encode the BitmapSource by one of the BitmapEncoders. Encode into a MemoryStream or a FileStream.
private byte[] ImageSourceToByteArray(ImageSource imageSrc)
{
if (symbolImage is BitmapSource bitmapSource)
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
using (var stream = new MemoryStream())
{
encoder.Save(stream);
return stream.ToArray();
}
}
return null;
}
In order to decode an image from a byte array, do not explictly use a specific BitmapDecoder. Better rely on automatic decoder selection, like shown below. It is also important to set BitmapCacheOption.OnLoad when the stream is closed right after decoding.
private ImageSource ByteArrayToImageSource(byte[] bytes)
{
using (var stream = new MemoryStream(bytes))
{
return BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}
I used
private BitmapImage byteArrayToImage(byte[] byteArrayIn)
{
try
{
MemoryStream stream = new MemoryStream();
stream.Write(byteArrayIn, 0, byteArrayIn.Length);
stream.Position = 0;
System.Drawing.Image img = System.Drawing.Image.FromStream(stream);
BitmapImage returnImage = new BitmapImage();
returnImage.BeginInit();
MemoryStream ms = new MemoryStream();
img.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
ms.Seek(0, SeekOrigin.Begin);
returnImage.StreamSource = ms;
returnImage.EndInit();
return returnImage;
}
catch (Exception ex)
{
throw ex;
}
return null;
}
This method in my application to convert byte array to an image. But it throws "Parameter is not valid" exception.. why it is happening..? Is there any alternative method.??
Hi this should be working:
private static BitmapImage LoadImage(byte[] imageData)
{
if (imageData == null || imageData.Length == 0) return null;
var image = new BitmapImage();
using (var mem = new MemoryStream(imageData))
{
mem.Position = 0;
image.BeginInit();
image.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
image.CacheOption = BitmapCacheOption.OnLoad;
image.UriSource = null;
image.StreamSource = mem;
image.EndInit();
}
image.Freeze();
return image;
}
If you have array like this:
byte[] byteArrayIn = new byte[] {255, 128, 0, 200};
And you want something like:
Use:
BitmapSource bitmapSource = BitmapSource.Create(2, 2, 300, 300,PixelFormats.Indexed8, BitmapPalettes.Gray256, byteArrayIn, 2);
Image.Source = bitmapSource;
In xaml:
<Image RenderOptions.BitmapScalingMode="NearestNeighbor" RenderOptions.EdgeMode="Aliased" x:Name="Image"></Image>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void btnBrowse_Click(object sender, RoutedEventArgs e)
{
var of = new OpenFileDialog();
of.Filter = "Image files (*.png;*.jpeg)|*.png;*.jpeg|All files (*.*)|*.*";
var res = of.ShowDialog();
if (res.HasValue)
{
imgPreview.Source = new BitmapImage(new Uri(of.FileName));
var t = Utils.ConvertBitmapSourceToByteArray(imgPreview.Source as BitmapSource);
var d = Utils.ConvertBitmapSourceToByteArray(new BitmapImage(new Uri(of.FileName)));
var s = Utils.ConvertBitmapSourceToByteArray(imgPreview.Source);
var enc = Utils.ConvertBitmapSourceToByteArray(new PngBitmapEncoder(), imgPreview.Source);
//imgPreview2.Source = Utils.ConvertByteArrayToBitmapImage(enc);
imgPreview2.Source = Utils.ConvertByteArrayToBitmapImage2(enc);
//var i = 0;
}
else
{
MessageBox.Show("Select a currect file...");
}
}
}
/util.cs/
public class Utils
{
public static byte[] ConvertBitmapSourceToByteArray(BitmapEncoder encoder, ImageSource imageSource)
{
byte[] bytes = null;
var bitmapSource = imageSource as BitmapSource;
if (bitmapSource != null)
{
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
using (var stream = new MemoryStream())
{
encoder.Save(stream);
bytes = stream.ToArray();
}
}
return bytes;
}
public static byte[] ConvertBitmapSourceToByteArray(BitmapSource image)
{
byte[] data;
BitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
return data;
}
public static byte[] ConvertBitmapSourceToByteArray(ImageSource imageSource)
{
var image = imageSource as BitmapSource;
byte[] data;
BitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
return data;
}
public static byte[] ConvertBitmapSourceToByteArray(Uri uri)
{
var image = new BitmapImage(uri);
byte[] data;
BitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
return data;
}
public static byte[] ConvertBitmapSourceToByteArray(string filepath)
{
var image = new BitmapImage(new Uri(filepath));
byte[] data;
BitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(image));
using (MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
return data;
}
public static BitmapImage ConvertByteArrayToBitmapImage(Byte[] bytes)
{
var stream = new MemoryStream(bytes);
stream.Seek(0, SeekOrigin.Begin);
var image = new BitmapImage();
image.BeginInit();
image.StreamSource = stream;
image.EndInit();
return image;
}
}
I am running a cron job in C# that takes 200,000 images and convert into 1 bit image. During running this job, sometimes the process crashes (even though I have global try catch), sometimes for some images(not all) it throws OutOfMemoryException and sometimes for some images it it throws A generic error occurred in GDI.
int pageSize = 1000;
for (int pageNumber = 0; pageNumber < 200; pageNumber++)
{
var imageUrls = allIMageUrls.Skip(pageSize * pageNumber).Take(pageSize).ToList();
var counter = 0;
var total = imageUrls.Count;
Logger.Log($"Page Number : {pageNumber}");
var failedImageUrls = new System.Collections.Concurrent.ConcurrentBag<string>();
Parallel.ForEach(imageUrls, imageUrl =>
{
try
{
Interlocked.Increment(ref counter);
var image = _httpService.DownloadImage(imageUrl);
if (image != null && image.Length > 0)
{
var oneBitImage = ConvertToOnebitFaxGroup4(contract);
_httpService.UploadImage(image, oneBitImage);
oneBitImage = null;
image = null;
}
}
catch (Exception ex)
{
failedImageUrls.Add(imageUrl);
Logger.Log(ex);
}
});
This is one time process. I added paging so that when it crashes I can restart from that page instead of start at beginning.
public static class ImageProcessor
{
static ImageCodecInfo _codecInfo;
static EncoderParameters _encoderParameters;
static ImageProcessor()
{
foreach (var codec in ImageCodecInfo.GetImageEncoders())
{
if (codec.MimeType == "image/tiff")
{
_codecInfo = codec;
break;
}
}
_encoderParameters = new EncoderParameters(2);
_encoderParameters.Param[0] = new EncoderParameter(Encoder.Compression, (long)EncoderValue.CompressionCCITT4);
_encoderParameters.Param[1] = new EncoderParameter(Encoder.ColorDepth, (long)1);
}
public static byte[] ConvertToOnebitFaxGroup4(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
var image = Image.FromStream(memoryStream);
var pData = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, pData, bytes.Length);
var bytesPerLine = (image.Width + 31) / 32 * 4;
var img = new Bitmap(image.Width, image.Height, bytesPerLine, PixelFormat.Format1bppIndexed, pData);
using (var ms = new MemoryStream())
{
image.Save(ms, _codecInfo, _encoderParameters);
img.Dispose();
Marshal.FreeHGlobal(pData);
return ms.ToArray();
}
}
}
Updated:
public static byte[] ConvertToOnebitFaxGroup4(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
using (var image = Image.FromStream(memoryStream))
{
var pData = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, pData, bytes.Length);
var bytesPerLine = (image.Width + 31) / 32 * 4;
using (var img = new Bitmap(image.Width, image.Height, bytesPerLine, PixelFormat.Format1bppIndexed, pData))
{
using (var ms = new MemoryStream())
{
img.Save(ms, _codecInfo, _encoderParameters);
Marshal.FreeHGlobal(pData);
return ms.ToArray();
}
}
}
}
}
Update2
public static byte[] ConvertToOnebitFaxGroup4(byte[] bytes)
{
using (var memoryStream = new MemoryStream(bytes))
{
using (var image = Image.FromStream(memoryStream))
{
using (var ms = new MemoryStream())
{
image.Save(ms, _codecInfo, _encoderParameters);
return ms.ToArray();
}
}
}
}
I need to convert a BitmapImage in a byte[] but I don't find how to do it in C# web.
I found examples but none of them work (JpegBitmapEncoder doesn't exist, BitmapImageObject.StreamSource doesn't exist, there isn't WriteableBitmap constructor with BitmapImage as parameter, Extensions.SaveJpeg(parameters) doesn't exist ...).
Examples I found:
Constructor new WriteableBitmap(bitmapImage) doesn't exist.
public static byte[] ConvertToBytes(this BitmapImage bitmapImage)
{
byte[] data;
// Get an Image Stream
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap btmMap = new WriteableBitmap(bitmapImage);
// write an image into the stream
Extensions.SaveJpeg(btmMap, ms,
bitmapImage.PixelWidth, bitmapImage.PixelHeight, 0, 100);
// reset the stream pointer to the beginning
ms.Seek(0, 0);
//read the stream into a byte array
data = new byte[ms.Length];
ms.Read(data, 0, data.Length);
}
//data now holds the bytes of the image
return data;
}
new WriteableBitmap(img), System.Windows.Media.Imaging.Extensions.SaveJpeg don't exist.
public static byte[] ImageToBytes(BitmapImage img)
{
using (MemoryStream ms = new MemoryStream())
{
WriteableBitmap btmMap = new WriteableBitmap(img);
System.Windows.Media.Imaging.Extensions.SaveJpeg(btmMap, ms, img.PixelWidth, img.PixelHeight, 0, 100);
img = null;
return ms.ToArray();
}
}
imageSource.StreamSource doesn't exist.
public static byte[] ImageToByte(BitmapImage imageSource)
{
Stream stream = imageSource.StreamSource;
Byte[] buffer = null;
if (stream != null && stream.Length > 0)
{
using (BinaryReader br = new BinaryReader(stream))
{
buffer = br.ReadBytes((Int32)stream.Length);
}
}
return buffer;
}
JpegBitmapEncoder doesn't exist.
byte[] data;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
using(MemoryStream ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
Try with the using statement to a namespace in the beginning of your code.
Otherwise there should be some Nuget packages which you could install to achieve your goal.
using System.Drawing;
In Main method
Image img = Image.FromFile("path to the file");
var byteArray = ImageToByte(img);
public static byte[] ImageToByte(Image img)
{
ImageConverter converter = new ImageConverter();
return (byte[])converter.ConvertTo(img, typeof(byte[]));
}
Try this
I think this will help...
public byte[] ConvertBitMapToByteArray(Bitmap bitmap)
{
byte[] result = null;
if (bitmap != null)
{
MemoryStream stream = new MemoryStream();
bitmap.Save(stream, bitmap.RawFormat);
result = stream.ToArray();
}
return result;
}
byte[] foo = System.IO.File.ReadAllBytes("bitmap path");
Or
byte[] foo;
Object obj = YourBitmap;
BinaryFormatter bf = new BinaryFormatter();
using (var ms = new MemoryStream())
{
bf.Serialize(ms, obj);
foo = ms.ToArray();
}
Or
ImageConverter foocon = new ImageConverter();
byte[] foo = (byte[])foocon.ConvertTo(YourBitmap, typeof(byte[]));
Or
MemoryStream ms = new MemoryStream();
Bitmap.Save(ms, YourBitmap.RawFormat);
byte[] foo = ms.ToArray();
Finally, it seems that, obviously, it missed some libraries but we are limited with our application, so we decided to recover our pictures by another way. Anyway, thank you all.
This is my code:
string photo = "somedata";
byte[] byt = System.Text.Encoding.UTF8.GetBytes(photo);
string strModified = Convert.ToBase64String(byt);
byte[] photoData = Convert.FromBase64String(strModified);
Image img = cnvrtToImg(photoData);
public Image cnvrtToImg(byte[] byteArrayIn)
{
using (MemoryStream mStream = new MemoryStream(byteArrayIn))
{
return Image.FromStream(mStream);
}
}
When the method cnvrtToImg is invoked, I get an error
Parameter is not valid
Please give me a solution
I think that System.Text.Encoding.UTF8 is not for image data, it is for text, not binary data. UTF8 just can't do some binary sequence. Base64 is the choice if you need convert binary to text.
I test with this, and confirm the cnvrtToImg is correct:
class Program
{
public static Image cnvrtToImg(byte[] byteArrayIn)
{
using (MemoryStream mStream = new MemoryStream(byteArrayIn))
{
return Image.FromStream(mStream);
}
}
static void Main(string[] args)
{
using (var file = File.Open(#"D:\0.jpg", FileMode.Open))
{
var buffer = new byte[file.Length];
file.Read(buffer, 0, (int) file.Length);
cnvrtToImg(buffer);
}
}
}
//finish