C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[1]: WPFでのDirectshow使用


(過去ログ 75 を表示中)

[トピック内 2 記事 (1 - 2 表示)]  << 0 >>

■44364 / inTopicNo.1)  WPFでのDirectshow使用
  
□投稿者/ ぴ区民 (1回)-(2009/12/07(Mon) 11:57:19)

分類:[C#] 

はじめまして、ぴ区民と申します。

現在WPFとc#にて動画を2つ入力して合成を行うアプリケーションの開発を行っています。
そこでDirectshow(c#でラップされたもの)を利用しようと思ったのですが、WPFにはHandleの概念がない(?)ようで
動画をGridやCanvasに貼りつけて再生するのも、どうやればいいのか検討も付かない状態です。

そもそもGridやCanvasといった物の上にDirectshowを用いて動画を載せることなど可能なのでしょうか?
もちろんWPFでの動画再生に関するもの(MediaElement等)は試して動くことを確認しておりますが、これでは動画の合成が厳しそうだと感じています。

なにぶん知識が足らず、Webで情報を探してはいますが有用な情報を見つけられません。
宜しければ、ご教授ください。

よろしくお願いします。


引用返信 編集キー/
■44383 / inTopicNo.2)  Re[1]: WPFでのDirectshow使用
□投稿者/ gtk2k (116回)-(2009/12/07(Mon) 19:02:33)
合成ならWPFでもとりあえずできます。
合成した画像をファイルに保存したりピクセルデータを取得することもできるので、
あとはDirectShowやVFW APIなどを使用してAVIやWMVなどに出力することができるのでは?
(DirectShowプログラミングやった事ないので詳しいことは分からない)

// サンプル
// Windows1 XAML
<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="356" Width="876">
    <Grid SnapsToDevicePixels="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="400"/>
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="250"/>
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid Name="grid1" Grid.Column="0" Grid.Row="0">
            <Rectangle Margin="0,0,100,50" SnapsToDevicePixels="True">
                <Rectangle.Fill>
                    <DrawingBrush Opacity="0.5">
                        <DrawingBrush.Drawing>
                            <VideoDrawing x:Name="MyVideoDrawingA"  Rect="0,0,300,200" />
                        </DrawingBrush.Drawing>
                    </DrawingBrush>
                </Rectangle.Fill>
            </Rectangle>
            <Rectangle Margin="102,59,0,0" SnapsToDevicePixels="True">
                <Rectangle.Fill>
                    <DrawingBrush Opacity="0.5">
                        <DrawingBrush.Drawing>
                            <VideoDrawing x:Name="MyVideoDrawingB"  Rect="0,0,300,200" />
                        </DrawingBrush.Drawing>
                    </DrawingBrush>
                </Rectangle.Fill>
            </Rectangle>
        </Grid>
        <Image Margin="6,0,12,3" Name="image1" Stretch="Fill" Grid.Column="1" />
        <Button Grid.Row="1" Height="23" Margin="0,6,0,0" Name="button1" VerticalAlignment="Top" HorizontalAlignment="Left" Width="76" Click="button1_Click">Play</Button>
        <Button Grid.Column="1" Grid.Row="1" HorizontalAlignment="Right" Margin="0,3,0,0" Name="button2" Width="75" Height="23" VerticalAlignment="Top" Click="button2_Click">保存</Button>
        <Label Grid.Column="1" Grid.Row="1" Margin="127,3,144,0" Name="label1" Height="28" VerticalAlignment="Top">↑Bitmapに描画したキャプチャ画像</Label>
    </Grid>
</Window>


// コード
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.IO;
using Microsoft.Win32;

namespace WpfApplication1
{
    public partial class Window1 : Window
    {
        DispatcherTimer tmr;
        MediaPlayer MyPlayerA, MyPlayerB;
        public Window1()
        {
            InitializeComponent();
            MyPlayerA = new MediaPlayer(); MyPlayerB = new MediaPlayer();
            MyPlayerA.Open(new Uri(@"d:\a.wmv", UriKind.Absolute)); MyPlayerB.Open(new Uri(@"d:\b.wmv", UriKind.Absolute));
            MyVideoDrawingA.Player = MyPlayerA; MyVideoDrawingB.Player = MyPlayerB;
            tmr = new DispatcherTimer();
            tmr.Interval =new TimeSpan(0, 0, 0, 0, 33);
            tmr.Tick += new EventHandler(tmr_Tick);
            MyPlayerA.MediaEnded += new EventHandler(MyPlayer_MediaEnded); MyPlayerB.MediaEnded += new EventHandler(MyPlayer_MediaEnded);
        }

        void MyPlayer_MediaEnded(object sender, EventArgs e)
        {
            tmr.Stop();
        }

        void tmr_Tick(object sender, EventArgs e)
        {
            image1.Source = CreateBitmapSourceFromVisual(grid1.ActualWidth, grid1.ActualHeight, grid1);
        }
        private void button1_Click(object sender, RoutedEventArgs e)
        {
            MyPlayerA.Play(); MyPlayerB.Play();
            tmr.Start();
        }

        private void button2_Click(object sender, RoutedEventArgs e)
        {
            MyPlayerA.Pause(); MyPlayerB.Pause();
            SaveFileDialog sfd = new SaveFileDialog();
            if (sfd.ShowDialog() == true)
                BitmapSave(grid1.ActualWidth, grid1.ActualHeight, grid1, sfd.FileName); 
            MyPlayerA.Play(); MyPlayerB.Play();
        }

        private static BitmapSource CreateBitmapSourceFromVisual(Double width, Double height, Visual visualToRender)
        {
            if (visualToRender == null)
                return null;
            RenderTargetBitmap bmp = new RenderTargetBitmap((Int32)Math.Ceiling(width), (Int32)Math.Ceiling(height), 96, 96, PixelFormats.Pbgra32);
            bmp.Render(visualToRender);
            return bmp;
        }
        
        private void BitmapSave(Double width, Double height, Visual visualToRender, string filename)
        {
            RenderTargetBitmap bmp = new RenderTargetBitmap((Int32)Math.Ceiling(width), (Int32)Math.Ceiling(height), 96, 96, PixelFormats.Pbgra32);
            bmp.Render(visualToRender);
            
            // ファイルに保存せずにピクセルデータを直接いじりたい場合は
            // RenderTargetBitmapのCopyPixelsメソッドでバイト配列などにピクセルデータをコピーできるので
            // コピー後あれこれする
            //int stride = (int)((bmp.PixelWidth * bmp.Format.BitsPerPixel + 7) / 8);
            //byte[] pixs = new byte[stride * bmp.PixelHeight];
            //bmp.CopyPixels(pixs, stride, 0);
            
            BitmapFrame bmf = BitmapFrame.Create(bmp);
            FileStream fs = new FileStream(filename, FileMode.Create);
            // jpgで保存
            JpegBitmapEncoder encoder = new JpegBitmapEncoder();
            encoder.QualityLevel = 100;
            encoder.Frames.Add(bmf);
            encoder.Save(fs);
            fs.Close();
        } 


    }
}

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -