How can I convert WriteableBitmap to BitmapImage? - c#

BitmapImage bitmapImage = new BitmapImage(new Uri("arka_projects_as_logo.png", UriKind.Relative));
Image uiElement = new Image() { Source = bitmapImage };
ScaleTransform t = new ScaleTransform() { ScaleX = 0.2, ScaleY = 0.2 };
WriteableBitmap writeableBitmap = new WriteableBitmap(uiElement,t);
I want to insert the result of this conversions (writeableBitmap) into System.Windows.Controls.Image. When I do this:
Image arkaImage = new Image() { Source = writeableBitmap };
arkaImage isn't shown at all. What can be done to make it work?

WriteableBitmap wb = ..
using (MemoryStream ms = new MemoryStream())
{
wb.SaveJpeg(ms, (int)image1.Width, (int)image1.Height, 0, 100);
BitmapImage bmp = new BitmapImage();
bmp.SetSource(ms);
}

Why don't you just apply the ScaleTransform to the UIElement as well?

Related

How to change foreground color for SVG images in WPF and c#

We are trying to get bitmap from SVG but its not giving the exact co-ordinate to change the pixel color.Can anyone help me how to change the color for bitmap pixel/svg pixel in wpf.
WpfDrawingSettings wpfDrawingSettings = new WpfDrawingSettings { IncludeRuntime = false, TextAsGeometry = false, OptimizePath = true };
StreamSvgConverter converter = new StreamSvgConverter(wpfDrawingSettings);
MemoryStream ms = new MemoryStream();
converter.Convert(str, ms);
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = ms;
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.EndInit();

Issue with PictureBox control

I have image file that i wanna crop and load to picturebox. When i download it remotely - all work fine, but when i load it from local machine - picturebox pic stretch...
var img = (Bitmap) Image.FromStream(new WebClient().OpenRead("https://i.snag.gy/MjJca5.jpg"));
img = CropImage(img);
BackgroundImage = img;
BackgroundImageLayout = ImageLayout.Zoom;
public Bitmap CropImage(Image img) {
// create a graphic path to hold the shape data
GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
var points = new Point[] {
new Point(85, 1111), new Point(934, 1111), new Point(934, 952), new Point(1642, 952),
new Point(1642, 2000), new Point(85, 2000), new Point(85, 1111)
};
GraphicsPath gp = new GraphicsPath();
gp.AddPolygon(points.ToArray());
Bitmap bmp1 = new Bitmap(2220, 2220);
using(Graphics G = Graphics.FromImage(bmp1)) {
G.Clip = new Region(gp);
G.DrawImage(img, 0, 0);
bmp1.Save("axi.jpeg");
return bmp1;
}
}
This code return this pic. All work correctly
but this code return this pic.
FileStream file = new FileStream(openFileDialog1.FileName, FileMode.Open);
var img = (Bitmap) Image.FromStream(file);
img = CropImage(img);
pictureBox1.BackgroundImage = img;
pictureBox1.BackgroundImageLayout = ImageLayout.Zoom;
...

Convert D3DImage to byte array

Is there any way to do that ?
I can cast the object to ImageSource and assign to Image but I have to be able to store it in byte[]. All the methods I found use casting to BitMap and that won't work here.
Here is a solution I found. The key was the use of DrawingVisual to create temporary image internally.
public static byte[] ImageToBytes(ImageSource imageSource)
{
var bitmapSource = imageSource as BitmapSource;
if (bitmapSource == null)
{
var width = (int)imageSource.Width;
var height = (int)imageSource.Height;
var dv = new DrawingVisual();
using (var dc = dv.RenderOpen())
{
dc.DrawImage(imageSource, new Rect(0, 0, width, height));
}
var rtb = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
rtb.Render(dv);
bitmapSource = BitmapFrame.Create(rtb);
}
byte[] data;
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
using (var ms = new MemoryStream())
{
encoder.Save(ms);
data = ms.ToArray();
}
return data;
}

How to center an image used as Grid Background through C# code?

I'm trying to set a Grid's backgroud through code.
The Grid has 1000 x 1000 size, the same size of the loaded PNG.
I load this PNG into a Stream, then execute the following code:
using (StreamWrapper wrapper = new StreamWrapper(streamImg))
using (BinaryReader reader = new BinaryReader(wrapper))
{
originalImage = new BitmapImage();
originalImage.BeginInit();
originalImage.CacheOption = BitmapCacheOption.OnLoad;
originalImage.StreamSource = reader.BaseStream;
originalImage.EndInit();
originalImage.Freeze();
}
ib = new ImageBrush() { ImageSource = ConvertToGrayScale(ref originalImage) };
grdQuebraCabeƧa.Background = ib;
private FormatConvertedBitmap ConvertToGrayScale(ref BitmapImage image)
{
FormatConvertedBitmap grayImage = new FormatConvertedBitmap();
grayImage.BeginInit();
grayImage.Source = image;
grayImage.DestinationFormat = PixelFormats.Gray32Float;
grayImage.EndInit();
return grayImage;
}
The following screenshot is the result:
You can see black blocks on lower and right sides.
I want to center the image in the grid.
Is that possible? How can I achieve this result?

Convert DrawingImage to BitmapImage

I want to draw large number of shapes (lines, ellipses and ...) and then save them as bitmap or png. I made the drawings and the question is: how can I convert a DrawingImage to BitmapImage in C#? the code is something like this:
DrawingGroup drawingGroup = new DrawingGroup();
using(DrawingContext context = drawingGroup.Open())
{
//make some drawing
}
DrawingImage drawingImage = new DrawingImage(drawingGroup)
// your suggestion? DrawingImage - > BitmapImage
You may put the ImageDrawing into an Image control and render that into a RenderTargetBitmap, which is a BitmapSource and can therefore be serialized by a BitmapEncoder (PngBitmapEncoder in this example).
public void SaveDrawingToFile(Drawing drawing, string fileName, double scale)
{
var drawingImage = new Image { Source = new DrawingImage(drawing) };
var width = drawing.Bounds.Width * scale;
var height = drawing.Bounds.Height * scale;
drawingImage.Arrange(new Rect(0, 0, width, height));
var bitmap = new RenderTargetBitmap((int)width, (int)height, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(drawingImage);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));
using (var stream = new FileStream(fileName, FileMode.Create))
{
encoder.Save(stream);
}
}
Note that you don't actually need a BitmapImage for encoding, because BitmapSource (or any derived class like RenderTargetBitmap) will be accepted as argument to BitmapFrame.Create.
A slightly different solution would involve a DrawingVisual instead of a DrawingImage:
public void SaveDrawingToFile(Drawing drawing, string fileName, double scale)
{
var drawingVisual = new DrawingVisual();
using (var drawingContext = drawingVisual.RenderOpen())
{
drawingContext.PushTransform(new ScaleTransform(scale, scale));
drawingContext.PushTransform(new TranslateTransform(-drawing.Bounds.X, -drawing.Bounds.Y));
drawingContext.DrawDrawing(drawing);
}
var width = drawing.Bounds.Width * scale;
var height = drawing.Bounds.Height * scale;
var bitmap = new RenderTargetBitmap((int)width, (int)height, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(drawingVisual);
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));
using (var stream = new FileStream(fileName, FileMode.Create))
{
encoder.Save(stream);
}
}
I found it pretty easy this way:
public static BitmapSource ToBitmapSource(DrawingImage source)
{
DrawingVisual drawingVisual = new DrawingVisual();
DrawingContext drawingContext = drawingVisual.RenderOpen();
drawingContext.DrawImage(source, new Rect(new Point(0, 0), new Size(source.Width, source.Height)));
drawingContext.Close();
RenderTargetBitmap bmp = new RenderTargetBitmap((int)source.Width, (int)source.Height, 96, 96, PixelFormats.Pbgra32);
bmp.Render(drawingVisual);
return bmp;
}
You may use it to get System.Drawing.Bitmap
using (MemoryStream ms = new MemoryStream())
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(ToBitmapSource(drawingImage)));
encoder.Save(ms);
using (System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ms))
{
bmpOut = new System.Drawing.Bitmap(bmp);
}
}

Categories