繁体   English   中英

WPF - 位图 - 额外的边框?

[英]WPF - Bitmap - extra borders?

我有一个程序可以通过单击从网络摄像头捕获帧。 捕获工作正常,我将其保存为位图,但我有一个奇怪的问题,即位图偏移 - 大小正确,但它从底部切掉了一部分(如图片的 25%)和顶部全黑。

任何想法是什么原因造成的?

流程如下:

public static string TempPicLocation = @"%USERPROFILE%\AppData\Local\temppic.bmp";

private void StartButton_Click(object sender, RoutedEventArgs e)
{
    int capturedeviceindex = cboDevices.SelectedIndex;
    FilterInfo cd = CaptureDevice[cboDevices.SelectedIndex];
    string cdms = cd.MonikerString;
    FinalFrame = new VideoCaptureDevice(cdms);
    FinalFrame.NewFrame += FinalFrame_NewFrame;
    FinalFrame.Start();
}

private void FinalFrame_NewFrame(object sender, NewFrameEventArgs eventArgs)
{
    var imageSource = ImageSourceForBitmap(eventArgs.Frame);
    imageSource.Freeze();

    this.Dispatcher.Invoke(
            new Action(
                () =>
                {
                    pboLive.Source = imageSource;
                    return;
                }
            )
            );
}

//If you get 'dllimport unknown'-, then add 'using System.Runtime.InteropServices;'
[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DeleteObject([In] IntPtr hObject);

public ImageSource ImageSourceForBitmap(Bitmap bmp)
{
    var handle = bmp.GetHbitmap();
    try
    {
        return Imaging.CreateBitmapSourceFromHBitmap(handle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
    }
    finally { DeleteObject(handle); }
}

private void CaptureButton_Click(object sender, RoutedEventArgs e)
{
    ImageSource Captured = pboLive.Source;
    pboSnap.Source = Captured.Clone();
    capturedpictures.Add(pboLive.Source);

    var filePath = Environment.ExpandEnvironmentVariables(TempPicLocation);

    ImageHandlers.SaveToBmp(pboLive, filePath);
}

internal static void SaveToBmp(FrameworkElement visual, string fileName)
{
    var encoder = new BmpBitmapEncoder(); //In System.Windows.Media.Imaging
    SaveUsingEncoder(visual, fileName, encoder);
}

internal static void SaveUsingEncoder(FrameworkElement visual, string fileName, BitmapEncoder encoder)
{
    //Here the commented part is the right size, but with 5k x 5k is used to check that the entire picture actually is there. And yes, it indeed is.
    //RenderTargetBitmap bitmap = new RenderTargetBitmap((int)visual.ActualWidth, (int)visual.ActualHeight, 96, 96, PixelFormats.Pbgra32); //In System.Windows.Media.Imaging
    RenderTargetBitmap bitmap = new RenderTargetBitmap(5000, 5000, 96, 96, PixelFormats.Pbgra32); //In System.Windows.Media.Imaging
    bitmap.Render(visual);
    BitmapFrame frame = BitmapFrame.Create(bitmap); //In System.Windows.Media.Imaging
    encoder.Frames.Add(frame);

    string filePath = fileName.Replace(Path.GetFileName(fileName), string.Empty);
    System.IO.Directory.CreateDirectory(filePath);

    using (var stream = File.Create(fileName))
    {
        encoder.Save(stream);
    }
}

https://social.msdn.microsoft.com/Forums/vstudio/en-US/984da366-33d3-4fd3-b4bd-4782971785f8/questions-about-rendertargetbitmap?forum=wpf

public static BitmapSource CreateBitmapFromVisual(Visual target, Double dpiX, Double dpiY)
    {
        if (target == null)
        {
            return null;
        }

        Rect bounds = VisualTreeHelper.GetContentBounds(target);

        RenderTargetBitmap rtb = new RenderTargetBitmap((Int32)(bounds.Width * dpiX / 96.0),
                                                                                           (Int32)(bounds.Height * dpiY / 96.0),
                                                                                           dpiX,
                                                                                           dpiY,
                                                                                           PixelFormats.Pbgra32);

        DrawingVisual dv = new DrawingVisual();
        using (DrawingContext dc = dv.RenderOpen())
        {
            VisualBrush vb = new VisualBrush(target);
            dc.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
        }

        rtb.Render(dv);

        return rtb;
    }

这段代码是由微软的某个人发布的,然后你可以这样做:

using (FileStream outStream = new FileStream(@"C:\mycanvas.png", FileMode.Create))
        {
            PngBitmapEncoder enc = new PngBitmapEncoder();
            enc.Frames.Add(BitmapFrame.Create(CreateBitmapFromVisual(myCanvas, 96, 96)));

            enc.Save(outStream);
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM