2017-10-05 10 views
-1

私はクリックでウェブカメラからフレームをキャプチャするプログラムを持っています。キャプチャは正常に動作し、ビットマップとして保存されますが、ビットマップがオフセットされているという奇妙な問題があります。サイズは正しいですが、画像の25%のような部分から、すべて黒です。WPF - ビットマップ - 余分なボーダー?

これを引き起こす原因は何ですか?

流れは以下のようになります:コードのこの作品は、Microsoftからのいくつかのいずれかによって掲示され、その後、あなたがこれを行うことができ

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); 
    } 
} 

答えて

-1

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); 
     }