I have a videosignal that provides me a buffer with a YCbCR-Signal. I can convert it to RGB by doing some math but I have no idea how to show the video in ,Net WPF. I also tried to use SlimDX and render the stream to a sprite but this is only an idea and I also don't have a clue how to start.
Thanks for help,
Meldur
If you can convert it to RGB, you have Bitmap in your hands. You can lock bitmap and set it's data. When you creating new Bitmap, you can set pixel format (24bpp, 32bpp), so creating Bitmap from video frame shouldn't be problem.
Every time you get new frame, all you need is to update texture in DirectX. Textures in DirectX has various formats and some of them are compatible with bitmap formats, you can even create new texture using Bitmap.
First find some examples how to render texture in DirectX (SlimDX, ManagedDirectX...), then update texture every time new frame comes in. If you don't want to bother with texture locking and updating, you can create new texture every time new frame comes, using this constructor
public Texture(Device, Bitmap, Usage, Pool);
Even if you don't want to bother with DirectX, you can render directly into Canvas in WPF
class MyCanvas : Canvas {
protected override void OnRender (DrawingContext dc) {
BitmapImage img = ...;
dc.DrawImage (img, new Rect (0, 0, img.PixelWidth, img.PixelHeight));
}
}
To get BitmapImage from Bitmap, look here link text
Related
So I've been struggling with this for a while. How can I turn a graphic that I drew into a bitmap and how can I keep it updated? I mean let's say I wanna draw some shapes and then go ahead and color some random areas using setPixel, getPixel etc by going pixel by pixel on the bitmap. I don't want the old drawings to dissapear, but to put the color on top of it if it makes sense. And also, how can I save the bitmap on the computer without getting just a black image?
I'm relatively new to c# and getting answers to these questions would mean the world to me.
To save a Bitmap is easy
Bitmap pic = new Bitmap(16, 16);//16x16 picture
//draw what you want
pic.Save("name.bmp");//save the drawed Bitmap
pic.Dispose();
With .Save you save the file.
With .Dispose you give the ressourses free from the picture, dispose the picture when you don't use the picture anymore.
I am trying to update the image by drawing circles every time mouse pointer is moved. The pixelBuffer is stored in map object and updated with CircleFilledWithGradientMethod(). I load the pixel buffer in to WriteableBitmap Bitmap and then try to display it by setting image source of an image element in my XAML UI to Bitmap. What happens, is that when I first move my mouse, I see the very first 2 circles drawn but then as I move the mouse, the image does not get updated. Why could that be? Is there a method I should call on Image to force it to redraw? The reason I use stream.WriteAsync two times, when I could have just used it one, is just to show that it is working properly.
private async void TextArea_PointerMoved(object sender, PointerRoutedEventArgs e)
{
Pixel pixel1 = new Pixel(255, 0, 0);
Pixel pixel2 = new Pixel(255, 255, 255);
map.CircleFilledWithGradient((int) pointer.Position.X, (int)pointer.Position.Y, 100, pixel1, pixel2);
using (Stream stream = Bitmap.PixelBuffer.AsStream())
{
stream.WriteAsync(map.pixelData, 0, map.pixelData.Length);
}
map.CircleFilledWithGradient((int)pointer.Position.X+100, (int)pointer.Position.Y, 100, pixel1, pixel2);
using (Stream stream = Bitmap.PixelBuffer.AsStream())
{
stream.WriteAsync(map.pixelData, 0, map.pixelData.Length);
}
this.Image.Source = Bitmap;
}
What I think is happening, is that as soon as I draw the image on the screen, it caches it, and then keeps using the old image. Or is it that the standard Image element does not support redrawing?
Update:
My Bitmap was a private class variable. If I do
WriteableBitmap Bitmap = new WriteableBitmap((int)this.ActualWidth, (int)this.Grid.RowDefinitions[1].ActualHeight);
It all starts to work, but isn't that memory inefficient? Aren't I allocating memory for each new WriteableBitmap each time I move my mouse. And as I have found out, the issue is definitely with with Image component. Why wouldn't it update when I just make changes to it's source, but updates when I change its source to a different object.
`
Is there a method I should call on Image to force it to redraw?
Close. There's a method on WriteableBitmap.
Call WriteableBitmap.Invalidate after you update it to request the refresh.
Assuming the Bitmap was already set as Image.Source, replace the line:
this.Image.Source = Bitmap;
With:
Bitmap.Invalidate();
Why wouldn't it update when I just make changes to its source, but updates when I change its source to a different object.
Setting the Image.Source to the same thing it's already set to is a noop. Most complex Properties ignore "changes" which don't change the existing value. Creating a new WriteableBitmap each time works (very inefficiently) because it's different.
I have a page in my MVC4 project where user can add its company logo using the file upload control. These images/logos are then shown on map in mobile application. We need to crop these images so that they can look like a Flag.
We need to take only the part of image inside the flag frame and leave the rest.
Can it be done using code in C#?
If yes, how it can be done. Please help me with some code samples and links.
I need to show a flag frame over the uploaded image, so that user can adjust its image in that frame, what it wants to be in the frame.
Please suggest me with some APIs and code samples.
Thanks.
Update: In some sites, when we upload profile image, it gives us a frame on top, and the image we have selected can be moved, so that the desired part comes into that frame. Now when we upload our profile image, it gets resized into that size. Can I do something similar here? in the frame above, I can give a flag shape, user can move the uploaded image, to get desired part of image in that frame.
Is it right approach?
How can we do this? I have looked into some jquery code samples, but no help.
You can use SetClip function with the Region as parameter:
https://msdn.microsoft.com/en-us/library/x1zb278e(v=vs.110).aspx
So you need to create Graphics object from Bitmap, set clip with the shape of your flag and then draw image on that Graphics object. That's all.
// Following code derives a cutout bitmap using a
// scizzor path as a clipping region (like Paint would do)
// Result bitmap has a minimal suitable size, pixels outside
// the clipping path will be white.
public static Bitmap ApplyScizzors(Bitmap bmpSource, List<PointF> pScizzor)
{
GraphicsPath graphicsPath = new GraphicsPath(); // specified Graphicspath
graphicsPath.AddPolygon(pScizzor.ToArray()); // add the Polygon
var rectCutout = graphicsPath.GetBounds(); // find rectangular range
Matrix m = new Matrix();
m.Translate(-rectCutout.Left, -rectCutout.Top); // translate clip to (0,0)
graphicsPath.Transform(m);
Bitmap bmpCutout = new Bitmap((int)(rectCutout.Width), (int)(rectCutout.Height)); // target
Graphics graphicsCutout = Graphics.FromImage(bmpCutout);
graphicsCutout.Clip = new Region(graphicsPath);
graphicsCutout.DrawImage(bmpSource, (int)(-rectCutout.Left), (int)(-rectCutout.Top)); // draw
graphicsPath.Dispose();
graphicsCutout.Dispose();
return bmpCutout;
}
I have a simple WPF application where I display one very large image (9000x2875) and on top of it, many small images (64x64).
To do this, I have a Canvas with one Image, then I programatically add the small images as they arrive.
Now I am trying to save portions of the composite image as png files. I thought I would use a RenderTargetBitmap to render the portion of the Canvas that I wanted. My problem is that I cannot find a good way to save the right portion of the image. Here is a my current hack:
private static void SaveImage(Canvas canvas, string file, int x, int y, int width, int height)
{
//changing 0,0 on the canvas so RenderTargetBitmap works as expected.
canvas.RenderTransform = new MatrixTransform(1d, 0d, 0d, 1d, -x, -y);
canvas.UpdateLayout();
RenderTargetBitmap bmp = new RenderTargetBitmap(width, height, 96d, 96d, Pixelformats.Pbgra32);
bmp.Render(canvas);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
using(Stream s = File.Create(file))
{
encoder.Save(s);
}
}
The obvious problem with this is that the display will change due to the RenderTransform. It also makes the application slower. I did try to do a RenderTargetBitmap of the entire canvas, but that was much slower than doing this.
So my questions are:
Is there an easier way to save just a portion of the viewed image?
If not, does someone have a suggestion for a better way to go about this? (I already tried a single WriteableBitmap, but that was about as slow as doing the RenderTargetBitmap of the entire canvas.
What you want to use is a CroppedBitmap, which will allow you to save a cropped portion of your image.
// (BitmapSource bmps)
CroppedBitmap crop = new CroppedBitmap(bmps, new Int32Rect(selRect.X, selRect.Y, selRect.Width, selRect.Height));
Edit: Since there seems to be no way to get this to perform the way you want in WPF I would suggest pre-cropping the large image using GDI+ (without displaying it) and loading the region of it you want onto a smaller canvas.
This is the high level problem I'm trying to solve...
I have a 3rd party plotting/graphing (IoComp Plot), and I want to embed a high quality (at least 600 dpi) bitmap of the Plot control in reports created by another 3rd party report package (Combit List & Label).
This is the approach that seems most promising so far...
---Edit---:
After trying many other approachs, the only one that I think I can make work is to create a hidden instance of the Plot control, with everything scaled up to printer size (approx 5 times screen size). That includes width and height, font sizes, line widths - every visible component of the control. Yuck!
------
I can get a Graphics object of the proper resolution from the plot control's PrintPage event, but converting it to a Bitmap so the report package will be happy is proving to be the major stumbling block. Several hours of searching has led to other people who asked the same question, but no viable answers.
The only promising lead I've found suggested using one of the Bitmap constructors, which takes a Graphics instance as a parameter.
However, it's not working for me. It creates Bitmap, but with no content from the Plot control - it is a pure black image.
Here's my code (edited to show drawing of red line to Graphics object):
void PrintDocument_PrintPage(object sender, PrintPageEventArgs e)
{
// Draw a red line on the Graphics object. When printed, this
// line is shown as part of the normal Plot graphics.
Pen myPen;
myPen = new Pen(Color.Red);
e.Graphics.DrawLine(myPen, 0, 0, 200, 200);
myPen.Dispose();
// Create a bitmap from the Graphics object
Bitmap bm = new Bitmap(1000, 1000, e.Graphics);
// Save to disk
// DOES NOT WORK - CREATES FILE THAT IS PURE BLACK (VIEWED
// WITH "PAINT" PROGRAM)
bm.Save(#"C:\Bicw_Dev\Bic.Net\FrontEnd\GraphicsToBmp.bmp", ImageFormat.Bmp);
bm.Dispose();
}
Can anyone suggest why this doesn't work? Is this even a valid approach?
Also, please note:
As far as I can determine (and I've spent quite a bit of time looking) there is no way to get a high resolution, print quality Bitmap from the Plot control directly!
I stress this because several others who asked the question got code samples in response that solved the opposite problem - converting a Bitmap to a Graphics.
I need to convert a Graphics object to a Bitmap object.
And if anyone can suggest an alternate approach that allows me to get a print quality image of my plots into my reports, please feel free. (For example, I can get a low quality (72 bpi) Bitmap from the Plot control, and have considered trying to stretch it - but I've never seen that approach work well in other applications).
Thanks,
-Tom Bushell
Edit in response to comment:
As an experiment, I added the following:
Pen myPen;
myPen = new Pen(Color.Red);
e.Graphics.DrawLine(myPen, 0, 0, 200, 200);
myPen.Dispose();
This caused a red line to be drawn over the plot graphics when I printed my plot. But it had no effect on the Bitmap - it's still pure black.
However, it's not working for me. It
creates Bitmap, but with no content
from the Plot control - it is a pure
black image.
Well you never do paint to the graphics, what do you expect?
You are suppose to do the actual drawing for the output in that event.
The constructor you're using does not copy any graphics, only sets the resolution equal to the graphics resolution. See msdn. As Leppie points out, you have to actually draw something to the bitmap. I suggest getting another graphics object for the item you just created.
Graphics g = Graphics.FromImage(bmp);
//Make the background white
g.FillRectangle(Brushes.White, 0, 0, 1000, 1000);
It is not easy to control the DPI in the Print(Preview) system.
But maybe you are going about it the wrong way. What you want is to create a (large) bitmap and then 'trick' the control in to using that bitmap as if it was the screen. See this list of links.
No need for PrintDocument.