「Xamarin.MacでNSImageをSystem.Drawing.Imageに変換する」の版間の差分

提供: MonoBook
ナビゲーションに移動 検索に移動
(ページの作成:「MonoMacにおいてMonoMac.AppKit.NSImageをSystem.Drawing.Imageに変換する方法を試行錯誤している。 ==方法1== NSImageは基本的にTIFFファイ...」)
 
imported>Administrator
 
(3人の利用者による、間の6版が非表示)
1行目: 1行目:
[[MonoMac]]においてMonoMac.AppKit.NSImageをSystem.Drawing.Imageに変換する方法を試行錯誤している。
+
Xamarin.MacにおいてAppKit.NSImageをSystem.Drawing.Imageに変換する方法を試行錯誤している。
  
 
==方法1==
 
==方法1==
7行目: 7行目:
 
     using System.Drawing;
 
     using System.Drawing;
 
     using System.IO;
 
     using System.IO;
     using MonoMac.Foundation;
+
     using Foundation;
     using MonoMac.AppKit;
+
     using AppKit;
  
 
     public static class NSImageExtentions
 
     public static class NSImageExtentions
25行目: 25行目:
 
</source>
 
</source>
  
なお、MonoMacのクラス群はほぼDisposeメソッドを実装しており、[[メモリリーク]]を防ぐために「using」が重要となる。
+
なお、Xamarin.Macのクラス群はほぼDisposeメソッドを実装しており[[メモリリーク]]を防ぐためにも「using」が重要となる。
大容量の[[メモリ]]を搭載している昨今の[[Mac]]では多少の[[メモリリーク]]をする[[アプリ]]でも大して問題にならないが、MonoMac.QTKitを使った[[ビデオキャプチャ]]などでは1フレームごとに上記のような処理が走り、1/30秒や1/60秒といった速度で多種多様な[[インスタンス]]が生成され続けるため、Disposeを怠ると凄い勢いで[[メモリリーク]]することになる。
+
大容量の[[メモリ]]を搭載している昨今の[[Mac]]では多少の[[メモリリーク]]をしても大して問題にならないが、QTKitやAV Foundationを使った[[ビデオキャプチャ]]などでは1/30秒や1/60秒といった速度で1フレームごとに上記のような処理が走るため、Dispose呼出を怠ると凄い勢いで[[メモリリーク]]することになる。
  
 
これに加えてビデオキャプチャではSystem.GC.Collectメソッドの手動実行も重要な場合がある。
 
これに加えてビデオキャプチャではSystem.GC.Collectメソッドの手動実行も重要な場合がある。
 
ビデオキャプチャなどの常時負荷が高い状況化では[[ガベージコレクション]]の自動実行だけでは処理が追いつかない場合があるようだ。
 
ビデオキャプチャなどの常時負荷が高い状況化では[[ガベージコレクション]]の自動実行だけでは処理が追いつかない場合があるようだ。
 
 
ちなみにSystem.GC.Collectをメインスレッド以外で実行しても効果がないようだ。
 
ちなみにSystem.GC.Collectをメインスレッド以外で実行しても効果がないようだ。
 
凄い嵌った。
 
凄い嵌った。
  
==関連項目==
+
== 関連項目 ==
*[[MonoMac]]
+
* [[Xamarin.Mac]]
*[[MonoMac/NSImageをファイルに保存する]]
+
* [[Xamarin.Mac/NSImageをファイルに保存する]]
 +
* [[Xamarin.Mac/System.Drawing.ImageをNSImageに変換する]]
  
==参考文献==
+
== 参考文献 ==
 
{{reflist}}
 
{{reflist}}
  
 
{{stub}}
 
{{stub}}
 +
 +
[[category:MonoMac]]
 +
[[category:Xamarin.Mac]]

2019年5月22日 (水) 05:13時点における最新版

Xamarin.MacにおいてAppKit.NSImageをSystem.Drawing.Imageに変換する方法を試行錯誤している。

方法1[編集 | ソースを編集]

NSImageは基本的にTIFFファイルのようなので、System.Drawing.Imageが読み込めるPNGファイルに変換を行い、ImageにStreamを食わせる。

    using System;
    using System.Drawing;
    using System.IO;
    using Foundation;
    using AppKit;

    public static class NSImageExtentions
    {
        public static Image ToImage(this NSImage image) 
        {
            using (var imageDataTiff = image.AsTiff()) 
            using (var imageRep = NSBitmapImageRep.ImageRepFromData(imageDataTiff) as NSBitmapImageRep)
            using (var imageProps = new NSDictionary())
            using (var imageDataPng = imageRep.RepresentationUsingTypeProperties(NSBitmapImageFileType.Png, imageProps))
            using (var imageStreamPng = imageDataPng.AsStream())
            { 
                return Image.FromStream(imageStreamPng);
            }
        }

なお、Xamarin.Macのクラス群はほぼDisposeメソッドを実装しておりメモリリークを防ぐためにも「using」が重要となる。 大容量のメモリを搭載している昨今のMacでは多少のメモリリークをしても大して問題にならないが、QTKitやAV Foundationを使ったビデオキャプチャなどでは1/30秒や1/60秒といった速度で1フレームごとに上記のような処理が走るため、Dispose呼出を怠ると凄い勢いでメモリリークすることになる。

これに加えてビデオキャプチャではSystem.GC.Collectメソッドの手動実行も重要な場合がある。 ビデオキャプチャなどの常時負荷が高い状況化ではガベージコレクションの自動実行だけでは処理が追いつかない場合があるようだ。 ちなみにSystem.GC.Collectをメインスレッド以外で実行しても効果がないようだ。 凄い嵌った。

関連項目[編集 | ソースを編集]

参考文献[編集 | ソースを編集]