Reputation:
I'm trying to draw lines on a graphic which I have stored as a byte array and then save as a jpg in my windows 10 universal app.
I have a byte[] which I have converted to a bitmapimage to get the pixel size using
BitmapImage bImage;
using (InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream())
{
using (DataWriter writer = new DataWriter(ms.GetOutputStreamAt(0)))
{
writer.WriteBytes(myByteArray);
await writer.StoreAsync();
}
bImage = new BitmapImage();
bImage.SetSource(ms);
}
Then I created a writeablebitmap using
WriteableBitmap writeableBmp = BitmapFactory.New(bImage.PixelWidth, bImage.PixelHeight).FromByteArray(myByteArray);
I then draw a line on the graphic
writeableBmp.DrawLine(10, 10, 200, 10, Colors.Black);
and then save it as a jpg
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("graphic.jpg");
using (var storageStream = await file.OpenAsync(FileAccessMode.ReadWrite))
{
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, storageStream);
var pixelStream = writeableBmp.PixelBuffer.AsStream();
var pixels = new byte[pixelStream.Length];
await pixelStream.ReadAsync(pixels, 0, pixels.Length);
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint)writeableBmp.PixelWidth, (uint)writeableBmp.PixelHeight, 48, 48, pixels);
await encoder.FlushAsync();
}
unfortunately the resulting image is just a thin horizontal line of colours. The original image is lost and no black line is shown.
I am new to graphics programming and the code snippets are basically just bits and pieces i've put together from various sources.
Any help is appreciated.
Upvotes: 0
Views: 192
Reputation:
Solved!
Changed:
WriteableBitmap writeableBmp = BitmapFactory.New(bImage.PixelWidth, bImage.PixelHeight).FromByteArray(myByteArray);
to:
WriteableBitmap writeableBmp = BitmapFactory.New(bImage.PixelWidth, bImage.PixelHeight).FromStream(new MemoryStream(myByteArray));
Upvotes: 0
Reputation: 3746
I've not found anything wrong with your encoding code. As long as you have valid raw data to create your initial WriteableBitmap, it should work.
My guess is that the error comes from the image data you are loading which are not valid. Something might be corrupted/improperly saved. You can try to display your BitmapImage and see if it loads properly. You can also use the BitmapImage.ImageFailed event for that. You can also check that you are actually retrieving some data from your stream by either checking the stream length and that if the cursor is set at position 0 before reading it.
Here is a sample code that generates a raw image and draw on it.
var width = 35;
var height = 35;
var imageData = new byte[width * height * 4];
for(var i = 0; i < imageData.Length; i += 4)
{
imageData[i] = 255;
imageData [i+1] = 0;
imageData [i+2] = 0;
imageData [i+3] = 255;
}
var image = BitmapFactory.New(width, height).FromByteArray(imageData); // source image data is ARGB
image.DrawLine(0,0, width -1, height -1, Colors.Red);
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("output.jpg", CreationCollisionOption.ReplaceExisting);
var outstream = await file.OpenAsync(FileAccessMode.ReadWrite);
var encoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, outstream);
var outImageData = image.PixelBuffer.ToArray();
encoder.SetPixelData(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Ignore, (uint) image.PixelWidth, (uint) image.PixelHeight, 96, 96, outImageData);
await encoder.FlushAsync();
outstream.Dispose();
Upvotes: 0