「Xamarin.MacでNSImageをSystem.Drawing.Imageに変換する」の版間の差分
ナビゲーションに移動
検索に移動
imported>Monobook 細 (Monobook がページ「MonoMac/NSImageをSystem.Drawing.Imageに変換する」を「Xamarin.Mac/NSImageをSystem.Drawing.Imageに変換する」に移動しました) |
|
(相違点なし)
|
2017年6月19日 (月) 04:12時点における版
MonoMacにおいてMonoMac.AppKit.NSImageをSystem.Drawing.Imageに変換する方法を試行錯誤している。
方法1
NSImageは基本的にTIFFファイルのようなので、System.Drawing.Imageが読み込めるPNGファイルに変換を行い、ImageにStreamを食わせる。
using System;
using System.Drawing;
using System.IO;
using MonoMac.Foundation;
using MonoMac.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);
}
}
なお、MonoMacのクラス群はほぼDisposeメソッドを実装しており、メモリリークを防ぐために「using」が重要となる。 大容量のメモリを搭載している昨今のMacでは多少のメモリリークをするアプリでも大して問題にならないが、MonoMac.QTKitを使ったビデオキャプチャなどでは1フレームごとに上記のような処理が走り、1/30秒や1/60秒といった速度で多種多様なインスタンスが生成され続けるため、Disposeを怠ると凄い勢いでメモリリークすることになる。
これに加えてビデオキャプチャではSystem.GC.Collectメソッドの手動実行も重要な場合がある。 ビデオキャプチャなどの常時負荷が高い状況化ではガベージコレクションの自動実行だけでは処理が追いつかない場合があるようだ。
ちなみにSystem.GC.Collectをメインスレッド以外で実行しても効果がないようだ。 凄い嵌った。