Generating thumbnail images in WPF - c#

How do I generate a thumbnail image in WPF in the following scenario?
using (MemoryStream mem = new MemoryStream(imgbytes))
{
BitmapImage jpgimage = new BitmapImage();
jpgimage.BeginInit();
jpgimage.CacheOption = BitmapCacheOption.OnLoad;
jpgimage.StreamSource = mem;
jpgimage.EndInit();
Image wpfimage = new Image();
wpfimage.Source = jpgimage.Clone();
lbx.Items.Add(wpfimage);
lbx.UpdateLayout();
Thread.Sleep(1000);
}

This one worked perfectly for me
<Image Width="120" Height="120" HorizontalAlignment="Center">
<Image.Source>
<BitmapImage DecodePixelWidth="100" DecodePixelHeight="100" UriSource="Garden.jpg" />
</Image.Source>
</Image>

Here's some code I'm using to convert an image I've downloaded from the web to a thumbnail image. Does this help? Presumably you can cut out the bits where I save it to file.
using (var ms = new MemoryStream(e.Result))
{
var bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = ms;
bi.DecodePixelWidth = _maxThumbnailWidth;
bi.EndInit();
var encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bi));
using (var fs = new FileStream(filename, FileMode.Create))
{
encoder.Save(fs);
}
}

Related

Button with transparent png image in .Net WPF

I have a WPF Button which should be displayed with a png image which has transparent areas.
This is my xaml code, which works for displaying an image:
<Button HorizontalAlignment="Left" VerticalAlignment="Top" Panel.ZIndex="2" Background="Transparent" BorderBrush="Transparent">
<Image Width="1cm" Height="1cm" x:Name="LogoImageChangeButton_Image"/>
</Button>
This is the image. As you can see, it has transparent areas:
Unfortunately, wpf seems to repeat or assume pixels in the transparent areas for some unknown reason. Unfortunately, the effect looks quite glitchy so I cant describe it any better:
I have tried around with different stretch modes, all seemed to have this issue. Any help is appreciated.
This is how I set the image:
LogoImageChangeButton_Image.Source = BitmapHelper_Net.BitmapConverter.Convert(Properties.Resources.ChangeImageIcon);
and this is how I convert the bitmap to an imagesource:
public static BitmapImage Convert(Bitmap src)
{
MemoryStream ms = new MemoryStream();
((System.Drawing.Bitmap)src).Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
BitmapImage image = new BitmapImage();
image.BeginInit();
ms.Seek(0, SeekOrigin.Begin);
image.StreamSource = ms;
image.EndInit();
return image;
}
Do not use BMP as conversion format. It does not support transparency.
Use PNG, and set BitmapCacheOption.OnLoad to be able to dispose of the stream after EndInit.
public static BitmapImage Convert(Bitmap src)
{
var image = new BitmapImage();
using (var ms = new MemoryStream())
{
src.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ms.Seek(0, SeekOrigin.Begin);
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = ms;
image.EndInit();
}
return image;
}

DataPackageView Bitmap looses transparency

Using the .NET framework, when retrieving the image from the clipboard by converting the IRandomAccessStreamReference, the transparency on .PNG images is lost. How can i prevent this?
var content = Windows.ApplicationModel.DataTransfer.Clipboard.GetContent();
if (content.Contains(StandardDataFormats.Bitmap))
{
IRandomAccessStreamReference imageReceived = await content.GetBitmapAsync();
BitmapImage bitmap = null;
using (IRandomAccessStreamWithContentType imageStream = await imageReceived.OpenReadAsync())
{
bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = imageStream.AsStream();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();
bitmap.Freeze();
}
}

How to assign StreamSource to BitmapImage in codebehind?

I have zip file in whick I store FlowDocument (Card.xaml) and folder with images (Media). Images in my FlowDocument have Tag, in which stores their path relative to FlowDocument. For image searching in FlowDocument (FindImages method): Finding all images in a FlowDocument
How I open this zip in RichTextBox. Please pay attention on how I create this images (bitmap), maybe problem there, but i can't understand what's wrong:
string nameOfXamlCardDefault = "Card.xaml";
private void Open_Executed(object sender, ExecutedRoutedEventArgs e)
{
OpenFileDialog dlg = new OpenFileDialog();
if (dlg.ShowDialog() == true)
{
//Open zip file
using (FileStream fullCardZipFile = File.Open(dlg.FileName, FileMode.Open, FileAccess.ReadWrite))
{
//Open zip by ZipArchive
using (ZipArchive archive = new ZipArchive(fullCardZipFile, ZipArchiveMode.Update))
{
//Get entry for xaml (FlowDocument)
ZipArchiveEntry xamlFileEntry = archive.GetEntry(nameOfXamlCardDefault);
//Open xaml
using (Stream xamlFileStreamInZip = xamlFileEntry.Open())
{
//Load FlowDocument into rtbEditor.Document
rtbEditor.Document = XamlReader.Load(xamlFileStreamInZip) as FlowDocument;
//Searching images
List<Image> images = FindImages(rtbEditor.Document).ToList();
foreach (var image in images)
{
var imageFileEntry = archive.GetEntry(image.Tag.ToString());
var bitmap = new BitmapImage();
using (Stream imageFileStream = imageFileEntry.Open())
{
var memoryStream = new MemoryStream();
imageFileStream.CopyTo(memoryStream);
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = memoryStream;
bitmap.EndInit();
image.Source = bitmap;
}
}
}
}
}
}
return;
}
All images in RichTextBox displays well, but there is no StreamSource in BitmapImage. And it will lead to error later:
<FlowDocument xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" NumberSubstitution.CultureSource="User" AllowDrop="True" PagePadding="5,0,5,0">
<Paragraph>
<Image Tag="Media/image0.png">
<Image.Source>
<BitmapImage CacheOption="OnLoad" BaseUri="{x:Null}"/>
</Image.Source>
</Image>
<Image Tag="Media/image1.png">
<Image.Source>
<BitmapImage CacheOption="OnLoad" BaseUri="{x:Null}"/>
</Image.Source>
</Image>
</Paragraph>
If just copy image and paste in RichTextBox, then it looks like this and this is good:
<Image Height="400" Width="600">
<Image.Source>
<BitmapImage CacheOption="OnLoad" UriSource="./Image1.bmp"
BaseUri="pack://payload:,,wpf1,/Xaml/Document.xaml"/>
</Image.Source>
Is it possible to embed images from zip like copy them and paste? I tried to use Clipboard and worked with MemoryStream. But it didn't help.
You should rewind the MemoryStream after copying the bitmap data, by setting its Position property or calling its Seek() method.
var imageFileEntry = archive.GetEntry(image.Tag.ToString());
if (imageFileEntry != null)
{
using (var imageFileStream = imageFileEntry.Open())
using (var memoryStream = new MemoryStream())
{
imageFileStream.CopyTo(memoryStream);
memoryStream.Position = 0; // here
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = memoryStream;
bitmap.EndInit();
image.Source = bitmap;
}
}
Instead of a BitmapImage, you could also decode a BitmapFrame from the stream.
var imageFileEntry = archive.GetEntry(image.Tag.ToString());
if (imageFileEntry != null)
{
using (var imageFileStream = imageFileEntry.Open())
using (var memoryStream = new MemoryStream())
{
imageFileStream.CopyTo(memoryStream);
memoryStream.Position = 0;
image.Source = BitmapFrame.Create(
memoryStream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}

Append image to image.source in wpf

I am trying to append image to image source but after executing the code image is not displaying in my page.
Code:
Bitmap bmp = (Bitmap)data.img;
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ms.Position = 0;
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();
imgPhoto.Source = bi;
this is data.img specifications that I want to append to imhPhoto.Source.
After working around this issue, the solution for this question is:
call the function to get BitmapImage and save it in photo variable like this:
BitmapImage photo = byteToImage(byte[] buffer)
this functionto convert byte to BitmapImage
public BitmapImage byteToImage(byte[] buffer)
{
using(var ms = new MemoryStream(buffer))
{
var image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = ms;
image.EndInit();
}
return image;
}
finally, append converted photo to image source like this:
imgPhoto.Source = photo;
You can assign path like this.
//for App folder path
//var path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location)+"\\Image\\pic.jpg";
//for machine path
var path = #"C:\Users\User1\Pictures\pic.jpg";
Bitmap bmp = new Bitmap(path);
MemoryStream ms = new MemoryStream();
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ms.Position = 0;
BitmapImage bi = new BitmapImage();
bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();
imgPhoto.Source = bi;
If this solves your problem :
System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(#"g:\screenshot.png");
BitmapImage bi = new BitmapImage();
bi.BeginInit();
MemoryStream ms = new MemoryStream();
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
ms.Position = 0;
bi.StreamSource = ms;
bi.EndInit();
imgPhoto.Source = bi;

How to create BitmapImage from a bmp file byte array?

In my wpf application I get a byte array of a bmp file.
I want to create a new System.Windows.Media.Imaging.BitmapImage.
I created MemoryStream from the byte array, but it doesn't work with SetSource.
Any suggestions ?
Add reference:
using System.IO;
Use the following code.
MemoryStream ms = new MemoryStream(imageArray);
Image image = Image.FromStream(ms);
For WPF
public static BitmapImage GetBitmapImage(byte[] imageArray)
{
using (var stream = new MemoryStream(imageArray))
{
var bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.StreamSource = stream;
bitmapImage.EndInit();
return bitmapImage;
}
}

Categories

Resources