How to fast convert BitmapSource to Bitmap? - .net-4.0

Can anyone suggest a way to convert a 2352x1726x8bit greyscale BitmapSource to Bitmap that is faster than the following taking about 600ms on a 3.2GHz P4:
public static Bitmap toBitmap(this BitmapSource bitmapsource)
{
Bitmap bitmap;
using (MemoryStream stream = new MemoryStream())
{
// from System.Media.BitmapImage to System.Drawing.Bitmap
PngBitmapEncoder enc = new PngBitmapEncoder();
enc.Frames.Add(BitmapFrame.Create(bitmapsource));
enc.Save(stream);
bitmap = new System.Drawing.Bitmap(stream);
}
return bitmap;
}

Related

Compress and save base64 image on Windows Phone 8.1

I have implemented the following solution to compress a base 64 image and get back the new base 64 string. It works fine in Windows Phone 8.0 but targeting Windows Phone 8.1 it seems that there are changes in the environment.
The WriteableBitmap has no constructor for a BitmapImage and the WriteableBitmap has no function SaveJpeg. I know that SaveJpeg is an extension, is there a way to add this extension to Windows Phone 8.1? Or is there any API which I can use? What do I have to change to make this 8.1 compatible? I'm kinda stuck with it here :-/
public static string Compress(String base64String, int compression)
{
String compressedImage;
byte[] imageBytes = Convert.FromBase64String(base64String);
MemoryStream memoryStream = new MemoryStream(imageBytes, 0, imageBytes.Length);
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.SetSource(memoryStream.AsRandomAccessStream());
WriteableBitmap bmp = new WriteableBitmap(bitmapImage);
int height = bmp.PixelHeight;
int width = bmp.PixelWidth;
int orientation = 0;
int quality = 100 - compression;
MemoryStream targetStream = new MemoryStream();
bmp.SaveJpeg(targetStream, width, height, orientation, quality);
byte[] targetImage = targetStream.ToArray();
compressedImage = System.Convert.ToBase64String(targetImage);
return compressedImage;
}
In WP8.1 Runtime I've used BitmapPropertySet to define a level of compression. Here below is sample code operating on Streams:
/// <summary>
/// Method compressing image stored in stream
/// </summary>
/// <param name="sourceStream">stream with the image</param>
/// <param name="quality">new quality of the image 0.0 - 1.0</param>
/// <returns></returns>
private async Task<IRandomAccessStream> CompressImageAsync(IRandomAccessStream sourceStream, double newQuality)
{
// create bitmap decoder from source stream
BitmapDecoder bmpDecoder = await BitmapDecoder.CreateAsync(sourceStream);
// bitmap transform if you need any
BitmapTransform bmpTransform = new BitmapTransform() { ScaledHeight = newHeight, ScaledWidth = newWidth, InterpolationMode = BitmapInterpolationMode.Cubic };
PixelDataProvider pixelData = await bmpDecoder.GetPixelDataAsync(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, bmpTransform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.DoNotColorManage);
InMemoryRandomAccessStream destStream = new InMemoryRandomAccessStream(); // destination stream
// define new quality for the image
var propertySet = new BitmapPropertySet();
var quality = new BitmapTypedValue(newQuality, PropertyType.Single);
propertySet.Add("ImageQuality", quality);
// create encoder with desired quality
BitmapEncoder bmpEncoder = await BitmapEncoder.CreateAsync(BitmapEncoder.JpegEncoderId, destFileStream, propertySet);
bmpEncoder.SetPixelData(BitmapPixelFormat.Rgba8, BitmapAlphaMode.Straight, newHeight, newWidth, 300, 300, pixelData.DetachPixelData());
await bmpEncoder.FlushAsync();
return destStream;
}

how to show images in RDLC report?

i have a column were i want the image to come out but at run-time only the name appears
MIMEType: image/jpeg Source: Database Value: =Fields!Image.Value
i saw this code but idk were to put it:
MemoryStream ms = new MemoryStream();
Image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return ms.ToArray();
please help
Do something like
Bitmap _img = new Bitmap(10, 10);
public byte[] MyPicture
{
get
{
// Generate bitmap
// Convert to stream
MemoryStream ms = new MemoryStream();
__img.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return ms.ToArray();
}
}

Convert BitmapImage to Byte[] in Silverlight4

can any one has idea. how to convert BitmapImage to Byte[] in silverlight4 application
i have one image file in .xap file.
BitmapImage bi = new BitmapImage(new Uri("images/GRed.png", UriKind.Relative));
now i want to convert BitmapImage to Byte[] and save in to db as binary format.
private byte[] ToByteArray(BitmapImage bi)
{
WriteableBitmap bmp = new WriteableBitmap(bi);
int[] p = bmp.Pixels;
int len = p.Length * 4;
byte[] result = new byte[len];
Buffer.BlockCopy(p, 0, result, 0, len);
return result;
}

Scaling PNG images in silverlight

In my application, I am accepting an image from user. If the image is more than specified size, then I am scaling down to appropriate size and saving in database. I am using FJCore library for scaling image. The library works well with JPEG images. But it does not support PNG images. It seems that library is not being updated recently. Any idea how can this be done in Silverlight?
What you can do is create a new Image element and set its source to a Writeable bitmap created from the stream but don't add this Image element to the visual tree. Create another WriteableBitmap of the final size you want and then call render on this WriteableBitmap passing the Image element and a ScaleTransform to resize the image to the appropriate size. You can then use the second WriteableBitmap as the source for a second Image element and add that to the visual tree.
I used WriteableBitmapEx project do acheive this. Here is the code if someone needs it.
private void ShowCustomImageButton_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openDialog = new OpenFileDialog();
openDialog.Multiselect = false;
openDialog.Filter = "PNG Files|*.PNG";
bool? userClickedOK = openDialog.ShowDialog();
if (userClickedOK == true)
{
BitmapImage image = new BitmapImage();
// get image that user has selected.
image.SetSource(openDialog.File.OpenRead());
WriteableBitmap wrtbmp = new WriteableBitmap(image);
// resize image if needed.
wrtbmp = wrtbmp.Resize(64, 64, WriteableBitmapExtensions.Interpolation.NearestNeighbor);
var img = wrtbmp.ToImage();
// convert image into file stream.
Stream filestram = img.ToStream();
filestram.Position = 0;
using (filestram)
{
// convert file stream into memory stream.
var memoryStream = new MemoryStream();
byte[] aryBuffer = new byte[16384];
int nRead = filestram.Read(aryBuffer, 0, aryBuffer.Length);
while (nRead > 0)
{
memoryStream.Write(aryBuffer, 0, nRead);
nRead = filestram.Read(aryBuffer, 0, aryBuffer.Length);
}
// use following line to convert in bytes and save into database.
memoryStream.ToArray();
imgCustomImage.Source = CreateBitmapImage(memoryStream);
}
}
}
private BitmapImage CreateBitmapImage(MemoryStream memoryStream)
{
if ((memoryStream == null) || (memoryStream.Length == 0))
return null;
var image = new BitmapImage();
image.SetSource(memoryStream);
return image;
}

Silverlight 4.0: How to convert byte[] to image?

public Image Base64ToImage(string base64String)
{
// Convert Base64 String to byte[]
byte[] imageBytes = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(imageBytes, 0,
imageBytes.Length);
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
System.Drawing.Image image = System.Drawing.Image.FromStream(ms, true);
return image;
}
I want to convert byte[] to image, however System.Drawing.Image is not supported in Silverlight. Any alternative?
You need to create an ImageSource and assign that to an Image control or use an ImageBrush to set on the background. BitmapImage is located in the System.Windows.Media.Imaging namespace.
byte[] imageBytes = Convert.FromBase64String(base64String);
using (MemoryStream ms = new MemoryStream(imageBytes, 0,
imageBytes.Length))
{
BitmapImage im = new BitmapImage();
im.SetSource(ms);
this.imageControl.Source = im;
}
or for the ImageBrush
byte[] imageBytes = Convert.FromBase64String(base64String);
using (MemoryStream ms = new MemoryStream(imageBytes, 0,
imageBytes.Length))
{
BitmapImage im = new BitmapImage();
im.SetSource(ms);
imageBrush.ImageSource = im;
this.BoxBorder.Background = imageBrush;
}
this code can convert image to byte[]
BitmapImage imageSource = new BitmapImage();
Stream stream = openFileDialog1.File.OpenRead();
BinaryReader binaryReader = new BinaryReader(stream);
currentImageInBytes = new byte[0];
currentImageInBytes = binaryReader.ReadBytes((int)stream.Length);
stream.Position = 0;
imageSource.SetSource(stream);
and this code can convert byte[] to image
public void Base64ToImage(byte[] imageBytes)
{
using (MemoryStream ms = new MemoryStream(imageBytes, 0, imageBytes.Length))
{
BitmapImage im = new BitmapImage();
im.SetSource(ms);
img.Source = im;
}
}
An other way:
public static BitmapImage ConvertStreamToImage(Stream stream)
{
BitmapImage _resultImage = new BitmapImage();
_resultImage.SetSource(stream);
return _resultImage;
}
which uses these name spaces:
using System.IO;
using System.Windows.Media.Imaging;