[![在此輸入圖片描述][1]][1]我有一個檔案夾,里面有一系列的jpgs,它們是被轉換為jpgs的視頻幀。 我做了一些代碼來迭代它們并顯示它們。
我試圖用C#在JPG圖片上畫一個綠框。高度、寬度、XC和YC都在一個XML中,我只是為每一幀訪問這些資料。我得到了使用位圖的作業,但為了在WPF中顯示它,我必須先將它轉換為位圖影像。問題是,這需要很長的時間。我希望視頻以25幀的速度播放,所以所有的處理需要在40毫秒內完成。現在,顯示新影像需要0.01到0.3秒的時間。
以下是我目前掌握的代碼-
public void UpdateImage(string imageName, int[] boxData)。
{
//imageName是影像的檔案路徑。
Bitmap oldImage = new Bitmap(imageName)。
//如果檢測到物體,則為Bitmap oldImage。
if (boxData.Length != 0)
{
//transforms x and y cords to align box better to light[/span]。
int newXC = boxData[0] - (boxData[2] /2) 。
int newYC = boxData[1] - (boxData[3] / 2) 。
//確保繩索不是負的。
if (newXC < 0)
newXC = 0;
if (newYC < 0)
newYC = 0;
//使用DrawRectangleBorder來繪制矩形。
Bitmap newImage = DrawRectangleBorder(oldImage, new Rectangle(new System.Drawing. Point(newXC, newYC), new System.Drawing.Size(boxData[2], boxData[3]), Color.Green)。)
//將Bitmap轉換為BitmapImage。
使用(MemoryStream memory = new MemoryStream()
{
newImage.Save(memory, ImageFormat.Png)。
memory.Position = 0;
BitmapImage bitmapImage = new BitmapImage()。
bitmapImage.Beginit();
bitmapImage.StreamSource = 記憶體。
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
ImportImage.Source = bitmapImage。
}
}
else。
{
Bitmap newImage = oldImage。
//將Bitmap轉換為BitmapImage。
using (MemoryStream memory = new MemoryStream())
{
newImage.Save(memory, ImageFormat.Png)。
memory.Position = 0;
BitmapImage bitmapImage = new BitmapImage()。
bitmapImage.Beginit();
bitmapImage.StreamSource = 記憶體。
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
ImportImage.Source = bitmapImage。
}
}
DrawRectangleBorder方法-
private static Bitmap DrawRectangleBorder(Bitmap image。矩形,顏色)。
{
//從舊的寬度和高度制作新的空白位圖。
Bitmap newBitmap = new Bitmap(image.Width, image.Height)。
//打開空白位。
使用 (Graphics graphics = Graphics.FromImage(newBitmap))
graphics.DrawImage(image, new Rectangle(0, 0, image.Width, image.Height)。
new Rectangle(0, 0, image.Width, image.Height), GraphicsUnit.Pixel)。)
//實際繪制的是矩形。
for (Int32 x = rectangle.Location.X; x <= rectangle.Right & & x < image.Width; x )
for (Int32 y = rectangle.Location.Y; y <= rectangle.Bottom & & y < image.Height; y )
if (y == rectangle.Location.Y || y == rectangle.Bottom || x == rectangle.Location.X || x == rectangle.Right)
newBitmap.SetPixel(x, y, color)。
return newBitmap。
下面是其中一張圖片的樣子,它們是640乘480的解析度------。 [1]: https://i.stack.imgur.com/ZiocC.jpg。 任何幫助都將是巨大的!
uj5u.com熱心網友回復:
你可以通過使用這個XAML來簡化你的代碼
<Canvas>
<Image x:Name="ImportImage"/>
<路徑 x:Name="ObjectBox""{Binding ActualWidth, ElementName=ImportImage}"
高度="{Binding ActualHeight, ElementName=ImportImage}"
Stretch="None"/span> Stroke="Green"/span> StrokeThickness="1"/span>/>
</Canvas>
用這樣一個UpdateImage方法:
public void UpdateImage(string imagePath, int[] boxData)。
{
ImportImage.Source = new BitmapImage(new Uri(imagePath))。
var boxes = new GeometryGroup()。
for (int i = 0; i <= boxData.Length - 4; i = 4)
{
int width = boxData[i 2] 。
int height = boxData[i 3] 。
int x = boxData[i] - width / 2;
int y = boxData[i 1] - height / 2;
boxes.Children.Add(new RectangleGeometry(new Rect(x, y, width, height))。
}
ObjectBox.Data = boxes;
}
uj5u.com熱心網友回復:
這里是一個粗略的演示,使用一個矩形覆寫在圖片前面,并控制其位置和大小。 對不起,以前從未在SO上分享過wpf,但認為這段代碼是你所需要的。 我測驗了一下時間,它可以遠低于40毫秒(但我根本沒有更新影像,只有矩形的覆寫。 如果需要的話,我還發現了這個快速視頻顯示WPF,但是雅,沒有實作它或測驗它。
".cs"
namespace ImageStreamer
{
// <summary>
// MainWindow.xaml的互動邏輯。
// </summary>/span>
public partial class MainWindow : Window
{
System.Windows.Threading.DispatcherTimer dispatcherTimer = new System.Windows.Threading.DispatcherTimer()。
Stopwatch stopWatch = new Stopwatch()。
long lastTime = 0;
public MainWindow()
{
InitializeComponent()。
dispatcherTimer.Tick = dispatcherTimer_Tick。
DispatcherTimer. Interval = new TimeSpan(0, 0, 0,0,25)。)
stopWatch.Start()。
}
private void dispatcherTimer_Tick(object sender, EventArgs e)。
{
targetRect.Margin = new Thickness(targetRect.Margin.Left 1, targetRect. targetRect.Margin.Top 1,0,0)。)
targetRect.Width = 1;
targetRect.Height = 1;
Trace.WriteLine(lastTime - stopWatch.ElapsedMilliseconds)。
lastTime = stopWatch.ElapsedMilliseconds;
}
private void Grid_Initialized(object sender, EventArgs e)。
{
}
private void Button_Click(object sender, RoutedEventArgs e)。
{
dispatcherTimer.Start()。
}
}
"xaml"
<Window x:Class="ImageStreamer.MainWindow"/span>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"/span>
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"/span>
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"/span>
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"/span>
xmlns:local="clr-namespace:ImageStreamer"/span>
mc:Ignorable="d"。
Title="MainWindow"/span> Height="450"/span> Width="800"/span>>
<Grid Initialized="Grid_Initialized">
<影像x: Name="imgBox" HorizontalAlignment="Left" Height="265" Margin="166, 87,0,0" VerticalAlignment="Top" Width="512" Source="/ZiocC. jpg"/>
<矩形x: Name="targetRect"/span> HorizontalAlignment="Left"/span> Height="49"/span> Margin="323,228,0, 0"/span> Stroke="Red"/span> VerticalAlignment="Top"/span> Width="113"/span> StrokeThickness="5"/span>/>
< Button Content="Button" HorizontalAlignment="Left" margin="24, 43,0,0" VerticalAlignment="Top" Click="Button_Click"/>
</Grid>
</Window>
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/323078.html
標籤:
