How make a Screenshot of UIElement in WPF

后端 未结 2 2007
甜味超标
甜味超标 2021-01-15 14:17

I have a problem with creating a screenshot of a scatterview. My screenshot always contains a black frame.

Here\'s my XAML-Code:



        
相关标签:
2条回答
  • 2021-01-15 14:39

    the following article has a workaround for your problem:

    Taking WPF “Screenshots”

    http://www.grumpydev.com/2009/01/03/taking-wpf-screenshots/

    ///
    /// Gets a JPG "screenshot" of the current UIElement
    ///
    /// UIElement to screenshot
    /// Scale to render the screenshot
    /// JPG Quality
    /// Byte array of JPG data
    public static byte[] GetJpgImage(this UIElement source, double scale, int quality)
    {
        double actualHeight = source.RenderSize.Height;
        double actualWidth = source.RenderSize.Width;
    
        double renderHeight = actualHeight * scale;
        double renderWidth = actualWidth * scale;
    
        RenderTargetBitmap renderTarget = new RenderTargetBitmap((int) renderWidth, (int) renderHeight, 96, 96, PixelFormats.Pbgra32);
        VisualBrush sourceBrush = new VisualBrush(source);
    
        DrawingVisual drawingVisual = new DrawingVisual();
        DrawingContext drawingContext = drawingVisual.RenderOpen();
    
        using (drawingContext)
        {
            drawingContext.PushTransform(new ScaleTransform(scale, scale));
            drawingContext.DrawRectangle(sourceBrush, null, new Rect(new Point(0, 0), new Point(actualWidth, actualHeight)));
        }
        renderTarget.Render(drawingVisual);
    
        JpegBitmapEncoder jpgEncoder = new JpegBitmapEncoder();
        jpgEncoder.QualityLevel = quality;
        jpgEncoder.Frames.Add(BitmapFrame.Create(renderTarget));
    
        Byte[] _imageArray;
    
        using (MemoryStream outputStream = new MemoryStream())
        {
            jpgEncoder.Save(outputStream);
            _imageArray = outputStream.ToArray();
        }
    
        return _imageArray;
    }
    

    hope this helps

    0 讨论(0)
  • 2021-01-15 14:42

    I found a quite simple way that works very well. Method TakeScreenshot makes a screenshot an returns it as a bitmap. MakeScreenShotButton_Click encodes the bitmap in jpeg, saves it, and sends it to the client as base64 String.

    Here are the code snippets. First TakeScreenshot:

    private Bitmap TakeScreenshot(int StartX, int StartY, int Width, int Height)
            {
                // Bitmap in right size
                Bitmap Screenshot = new Bitmap(Width, Height);
                Graphics G = Graphics.FromImage(Screenshot);
                // snip wanted area
                G.CopyFromScreen(StartX, StartY, 0, 0, new System.Drawing.Size(Width, Height), CopyPixelOperation.SourceCopy);
    
                // save uncompressed bitmap to disk
                string fileName = "C:\\TestBMP.bmp";
                System.IO.FileStream fs = System.IO.File.Open(fileName, System.IO.FileMode.OpenOrCreate);
                Screenshot.Save(fs, System.Drawing.Imaging.ImageFormat.Bmp);
                fs.Close();
    
                return Screenshot;
            }
    

    And that's the MakeScreenShotButton_Click:

    private void MakeScreenShotButton3_Click(object sender, RoutedEventArgs e)
        {
            // Start values
            System.Windows.Point absolutPosition = ScatterViewScreenShot.TranslatePoint(new System.Windows.Point(0, 0), sw1);
            System.Windows.Point screenPosition = this.PointToScreen(absolutPosition);
    
            // Catch width and hight of scatterview
            int widthScatterView = (int)ScatterViewScreenShot.ActualWidth;
            int heightScatterView = (int)ScatterViewScreenShot.ActualHeight;
    
            // Screenshot as bitmap TakeScreenshot(StartWert_X, StartWert_Y, BreiteBild, HöheBild)
            Bitmap screen = TakeScreenshot((int)screenPosition.X, (int)screenPosition.Y, widthScatterView, heightScatterView);
    
            MemoryStream ms = new MemoryStream();
    
            try
            {
                //ImageCodecInfo - Object
                ImageCodecInfo jpegCodec = null;
    
                // Quality-Parameter
                EncoderParameter qualitaetsParameter = new EncoderParameter(
                            System.Drawing.Imaging.Encoder.Quality, 40L);
    
                //Show available Codes in List
                ImageCodecInfo[] alleCodecs = ImageCodecInfo.GetImageEncoders();
    
                EncoderParameters codecParameter = new EncoderParameters(1);
                codecParameter.Param[0] = qualitaetsParameter;
    
                //Find Jpeg-Codec
                //Codec-Info-Object 
                for (int i = 0; i < alleCodecs.Length; i++)
                {
                    if (alleCodecs[i].MimeType == "image/jpeg")
                    {
                        jpegCodec = alleCodecs[i];
                        break;
                    }
                }
    
                // save image in stream
                screen.Save(ms, jpegCodec, codecParameter);
            }
            catch (Exception k)
            {
                throw k;
            }
    
            // Convert image in Byte-Array 
            byte [] imageBytes = ms.ToArray();
    
            // Convert Byte-Array in Base64String --> Image as String
            string bildBase64 = Convert.ToBase64String(imageBytes);
    
            TCP_Client client = new TCP_Client("192.168.5.3", 4321);
            client.sendeNachricht(bildBase64);
        }
    

    It works without problems!

    Cheers, Dennis

    0 讨论(0)
提交回复
热议问题