[英]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);
}
}
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.