F#でWPF --- BitmapImageで画像ロード

下記記事にてOpenCVと連携して画像を表示しました。

画像を読み込むだけであればWPFの標準セットで可能であるため、今回はWPFで画像をロードして表示してみます。

ついでにグレースケール化も行ってみます。

作成するアプリケーション

ファイルダイアログで画像を選び、表示するアプリケーションを作成します。
f:id:any-programming:20170306214920p:plain

アプリケーションコード

読込にはBitmapImageを利用します。(読込失敗の場合は例外が発生します。)

グレースケール化は、FormatConvertedBitmapを利用します。

その他ColorConvertedBitmap、TransformedBitmapなど色々あります。

Xamlは上記記事のものをそのまま使います。

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
        xmlns:local="clr-namespace:Actions;assembly=OpenCVSample"
        Title="MainWindow" Height="250" Width="400">
    <Grid>
        <Button Content="画像を開く" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="100">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="Click">
                    <local:OpenFileDialogAction Command="{Binding LoadImage}" />
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Button>
        <UniformGrid Margin="10,40,10,10" Columns="2">
            <Image Source="{Binding SrcImage}" />
            <Image Source="{Binding DstImage}" />
        </UniformGrid>
    </Grid>
</Window>

F#もupdateModel以外は上記記事のものをそのまま使います。

open System
open System.Windows
open System.Windows.Media
open System.Windows.Media.Imaging

type Model = 
    { SrcImage : BitmapSource 
      DstImage : BitmapSource }

let initialModel = 
    { SrcImage = null 
      DstImage = null }

type Msg = LoadImage of string

let updateModel model msg =
    match msg with
    | LoadImage x -> 
        let bmp = try BitmapImage(Uri(x))       
                  with | _ -> failwith "not supported"
        let gray = FormatConvertedBitmap(bmp, PixelFormats.Gray8, null, 0.0)
        { model with SrcImage = bmp
                     DstImage = gray }

[<STAThread>]
[<EntryPoint>]
let main argv = 
    let window = Application.LoadComponent(Uri("MainWindow.xaml", UriKind.Relative)) :?> Window
    window.DataContext <- DataContext(initialModel, updateModel, id)
    Application().Run(window) |> ignore   
    0