How want to save the image of a canvas to a file.
var img = new WriteableBitmap(canvas1, null);
Image i = new Image();
i.Source = img;
var bitmap = new Bitmap(i);
I tried to use bitmap.Save( for saving the image but Bitmap is not supported by silverlight.
How would you save WriteableBitmap to a file?
The WriteableBitmap has a Pixels collection which can be used to access the rendered image. However you really need to get it stored in a known format (preferable PNG).
The imagetools codeplex project can do that for you.
See this blog for a simple example of using it for your purposes.
Related
as you can read from the title i want to be able to draw some images on the screen, move them in some direction and video capture the movement with a good fps rate.
I want to specify that i do not want to record the desktop nor some portion of it but the content of the actual window in which the images are moving(so the window can also be minimized). Also if possible i want to be able to set a custom size for my view where everything will happen.
Where i should start from?
I have already tried with WPF but as the UI is single threaded i am not able to take a screenshot of the view while something is moving on it.
What library you would suggest me?
Are there similar open-source projects i can learn from?
Any suggestion i welcomed!
Here's some code I recently wrote to do this, it cycles through a number of frames and renders a control (in this case, a Canvas) into PNGs:
private void Export(int frame)
{
// force the control to update after any changes you've just made
theCanvas.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
// render the control into a bitmap
RenderTargetBitmap bitmap = new RenderTargetBitmap(1920, 1080, 96, 96, PixelFormats.Pbgra32);
bitmap.Render(theCanvas);
// save the bitmap out as a PNG
using (var stream = File.Create($"Animation/Frame_{frame.ToString("D3")}.png"))
{
var encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bitmap));
encoder.Save(stream);
}
}
You can then use ffmpeg to pack those PNGs into the movie file format of your choice.
I am trying to display image using BitmapImage for some time and it worked.I have changed the image and it stopped working.
For Bitmapimage I was using this code:
`ms.Seek(0, SeekOrigin.Begin); // ms is memory stream
BitmapImage b = new BitmapImage();
b.SetSource(ms);
image.ImageSource = b;`
I have ran into piece of code where it was checking if the length of the bytes[] ==14400
if(bytes.length == 14400)
{
var bmp = new WriteableBitmap(width, height);
Buffer.BlockCopy(buffer, 0, bmp.Pixels, 0, buffer.Length);
}
I want to know when to use WriteableBitmap and BitmapImage .
From iProgrammer:
Bitmaps are generally implemented as immutable objects. What this means is that once you create a bitmap you can't make any changes to it. You can manipulate bitmaps by creating new versions, which then immediately become immutable....
The WriteableBitmap, as its name suggests, isn't immutable and you can get at its individual pixels and manipulate them as much as you want. This is the ideal way to work when you need dynamic bitmaps.
iProgrammer - WriteableBitmap
From MSDN:
"Use the WriteableBitmap class to update and render a bitmap on a per-frame basis..." MSDN - WriteableBitmap Class
The Examples section of the MSDN article also shows how to update a WritableBitmap image when responding to mouse events. The code in the example erases pixels of the image by setting the pixel's ARGB values to 0 when the mouse's right button is down. The code also shows how to update individual pixels in the image where the mouse's left button is down. Essentially the code shows a rudimentary pixel image editor.
The point, however, is that you can't change image data when using regular bitmap - you have to use WritableBitmap instead. You can, however, render both if you wish.
Can you look at the code below?
Image img = new Image();
BitmapImage bi = new BitmapImage();
bi.UriSource = new Uri("OryxAntelope.jpg", UriKind.Relative);
img.Source = bi;
LayoutRoot.Children.Add(img);
It works fine.
But after I comment last line of code(//LayoutRoot.Children.Add(img);) picture not downloads.
What is the problem of this approach?
Thanks,
Vitaliy
The image is fetched only when it is first displayed. That is occurring after you add it to the layout (and the layout becomes visible).
What are you trying to accomplish? The example does not make it clear what the end result is.
Check out this article. You need to first download the image asynchronously with the WebClient control, and then you will be able to use/display it as you want. What I've done is set up a callback function, since its asynchronous, and you could put your code example in that function so that you don't try to add the image before it's finished downloading.
Hope this helps!
How do I get loading progress with the percent loaded info when an image is loading?
I have this:
Image image = new Image();
image.Source = new BitmapImage(new Uri("http://somesite.com/someimage.jpg"));
I expected something like this:
image.Loading += RoutedEventHandler(image_Loading);
but I can't find any such event. There is Loaded (not related to loading the source) and ImageOpened (which fires after loading the source is complete and has effected a layout pass).
I know it is possible because I have seen other apps indicate loading progress for images (for example "img news reader"). Is this possible with the standard Image Control, is there a 3rd party control that provides this, or do I have to write my own?
DownloadProgress is the event I was looking for, and it was hiding in the BitmapImage class:
Image image = new Image();
BitmapImage myBitmap = new BitmapImage(new Uri("http://somesite.com/someimage.jpg", UriKind.Absolute));
myBitmap.DownloadProgress += new EventHandler<DownloadProgressEventArgs>(myBitmap_DownloadProgress);
image.Source = myBitmap;
This is my first day with Silverlight. I’m trying to prototype an application which (among other functions) should be able to resize user supplied images. It should be able to handle and display several resized images at once. The most obviously approaches I've tried seem to "leak" memory in the sense that the original bitmaps are still being referenced in some way which causes Silverlight to allocate hundreds of megabytes of memory after a while. I just want to be able to load the images one by one, resize them and keep the small versions.
To be precise, I've tried the following:
Creating a list of System.Windows.Controls.Image's (and scaling them). I'm not surprised that this has not worked.
Creating a list of rectangles filled by image brushes. I'm not surprised either.
Rendering the bitmaps into System.Windows.Media.Imaging.WriteableBitmap. I expected this to perform well; I assumed that the bitmaps are really just drawn directly and not referenced in any way. However, the memory consumption indicated otherwise.
Here is a snippet of the relevant piece of code:
// create image source
Stream stream = file.OpenRead();
BitmapImage bmpImg = new BitmapImage();
bmpImg.SetSource(stream);
stream.Close();
// create temporary image from it
Image tmpImg = new Image();
tmpImg.Source = bmpImg;
// this is required by WriteableBitmap
tmpImg.Measure(new Size(100, 100));
tmpImg.Arrange(new Rect(0, 0, 100, 100));
// prepare scaling to 100x100
ScaleTransform scaleTrans = new ScaleTransform();
double scale = (double)100 / (double)Math.Max(bmpImg.PixelHeight, bmpImg.PixelWidth);
scaleTrans.CenterX = 0;
scaleTrans.CenterY = 0;
scaleTrans.ScaleX = scale;
scaleTrans.ScaleY = scale;
// render
WriteableBitmap writeableBitmap = new WriteableBitmap(100, 100);
writeableBitmap.Render(tmpImg, scaleTrans);
writeableBitmap.Invalidate();
// final image
Image img = new Image();
img.Source = writeableBitmap;
I hope I'm not missing anything silly, but it looks to OK to me and does the right thing (except the memory problem). Please also bear in mind that code quality is not supposed to be a production quality; it’s just a quick and dirty prototype.
I noticed that I’m not alone; I found questions related to image manipulation in Silverlight. I’m also aware of the fact that I could use some third party library, do processing on the server or write something even myself, but I’m surprised that Silverlight does not offer any basic image manipulation functions. It does not seem to be an uncommon requirement given where Silverlight positions itself.
Have you looked at the WriteableBitmapEx project? It's an open source project with a tonne of extension methods for the WriteableBitmap class. Here's how you resize:
BitmapImage image = new BitmapImage();
image.SetSource(dialog.File.OpenRead());
WriteableBitmap bitmap = new WriteableBitmap(image);
WriteableBitmap resizedBitmap = bitmap.Resize(500, 500, WriteableBitmapExtensions.Interpolation.Bilinear);
// For uploading
byte[] data = resizedBitmap.ToByteArray();
I don't know about the specifics here, but if you're leaking resources - you might look at which of your objects implements the IDisposable interface. I would guess that the Stream and Image classes implement this interface. And if they do - calling Dispose() on them (or wrapping their usage in a "Using" statement) will cause them to free their resources immediately rather than waiting for the garbage collector to kick in eventually.