「Xamarin.Macで画素配列からCGImageを生成する」の版間の差分
ナビゲーションに移動
検索に移動
imported>Administrator (→RGB画像) |
Administrator (トーク | 投稿記録) 細 (Administrator がページ「Xamarin.Mac/画素配列からCGImageを生成する」を「Xamarin.Macで画素配列からCGImageを生成する」に移動しました) |
||
(他の1人の利用者による、間の4版が非表示) | |||
2行目: | 2行目: | ||
== RGB画像 == | == RGB画像 == | ||
− | + | RGBなのでコンポーネント数は3で問題ないと思う。 | |
<source lang="csharp"> | <source lang="csharp"> | ||
public static CGImage CreateImage() | public static CGImage CreateImage() | ||
43行目: | 43行目: | ||
return cgImage; | return cgImage; | ||
} | } | ||
+ | </source> | ||
+ | |||
+ | 拾ってきたLennaの画像は正常にデコードできたようだ。 | ||
+ | 画素の入ったbyte配列をCGDataProviderクラスで[[ラップ]]してCGImageの[[コンストラクタ]]に渡すのがポイント。 | ||
+ | <source> | ||
+ | var error = ""; | ||
+ | var header = new JlsParameters(); | ||
+ | var dst = new MemoryStream(); | ||
+ | var path = Path.Combine(NSBundle.MainBundle.BundlePath, "Contents", "Resources", "lena24b.jpg"); | ||
+ | var src = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None); | ||
+ | var result = Jpeg.Decode(dst, src, header, out error); | ||
+ | Console.WriteLine(header); | ||
+ | |||
+ | dst.Seek(0, SeekOrigin.Begin); | ||
+ | var buf = dst.ToArray(); | ||
+ | |||
+ | // 画素データ | ||
+ | var data = new CGDataProvider(buf); | ||
+ | var colorspace = CGColorSpace.CreateDeviceRGB(); | ||
+ | |||
+ | var cgImage = new CGImage( | ||
+ | header.width, | ||
+ | header.height, | ||
+ | header.bitsPerSample, | ||
+ | header.bitsPerSample * header.components, | ||
+ | header.components * header.width, | ||
+ | colorspace, | ||
+ | CGBitmapFlags.ByteOrderDefault, | ||
+ | data, | ||
+ | decode: null, | ||
+ | shouldInterpolate: false, | ||
+ | intent: CGColorRenderingIntent.Default); | ||
+ | |||
+ | var nsImage = new NSImage(cgImage, new CGSize(cgImage.Width, cgImage.Height)); | ||
</source> | </source> | ||
97行目: | 131行目: | ||
== 関連項目 == | == 関連項目 == | ||
+ | * [[Xamarin.Mac/CGImageをNSImageに変換する]] | ||
+ | * [[Xamarin.Mac/CGImageをファイルに保存する]] | ||
== 参考文献 == | == 参考文献 == |
2019年12月25日 (水) 08:04時点における最新版
勉強がてらJPEGのコーデックをC#で実装してみているのだが、デコード済みの画素データが格納されたbyte配列からCGImageを生成したい。
RGB画像[編集 | ソースを編集]
RGBなのでコンポーネント数は3で問題ないと思う。
public static CGImage CreateImage()
{
var colorSpace = CGColorSpace.CreateDeviceRGB();
var width = 512;
var height = 512;
var bitsPerSample = 8;
var components = 3;//RGB
var bitsPerPixel = bitsPerSample * components;
var bytesPerRow = bitsPerPixel / 8 * width;
var buffer = new byte[width * height * components];
int a = 0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
var c = (byte)((1 << bitsPerSample) * ((float)y / width));
buffer[a++] = c;
buffer[a++] = 0;
buffer[a++] = 0;
}
}
var data = new CGDataProvider(buffer);
var cgImage = new CGImage(
width,
height,
bitsPerSample,
bitsPerPixel,
bytesPerRow,
colorSpace,
CGBitmapFlags.ByteOrderDefault,
data,
decode: null,
shouldInterpolate: false,
intent: CGColorRenderingIntent.Default);
return cgImage;
}
拾ってきたLennaの画像は正常にデコードできたようだ。 画素の入ったbyte配列をCGDataProviderクラスでラップしてCGImageのコンストラクタに渡すのがポイント。
var error = "";
var header = new JlsParameters();
var dst = new MemoryStream();
var path = Path.Combine(NSBundle.MainBundle.BundlePath, "Contents", "Resources", "lena24b.jpg");
var src = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.None);
var result = Jpeg.Decode(dst, src, header, out error);
Console.WriteLine(header);
dst.Seek(0, SeekOrigin.Begin);
var buf = dst.ToArray();
// 画素データ
var data = new CGDataProvider(buf);
var colorspace = CGColorSpace.CreateDeviceRGB();
var cgImage = new CGImage(
header.width,
header.height,
header.bitsPerSample,
header.bitsPerSample * header.components,
header.components * header.width,
colorspace,
CGBitmapFlags.ByteOrderDefault,
data,
decode: null,
shouldInterpolate: false,
intent: CGColorRenderingIntent.Default);
var nsImage = new NSImage(cgImage, new CGSize(cgImage.Width, cgImage.Height));
インデックスカラー画像[編集 | ソースを編集]
ついでにインデックスカラーも試してみた。
public static CGImage CreateIndexedImage()
{
var colors = new byte[] {
0, 0, 0,
63, 0, 0,
127, 0, 0,
191, 0, 0,
255, 0, 0
};
var colorSpace = CGColorSpace.CreateIndexed(CGColorSpace.CreateDeviceRGB(), colors.Length / 3, colors);
var width = 512;
var height = 512;
var bitsPerSample = 8;
var components = 1;// Indexed Color
var bitsPerPixel = bitsPerSample * components;
var bytesPerRow = bitsPerPixel / 8 * width;
var buffer = new byte[width * height * components];
int a = 0;
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
var c = (byte)((colors.Length / 3) * ((float)y / width));
buffer[a++] = c;
}
}
var data = new CGDataProvider(buffer);
var cgImage = new CGImage(
width,
height,
bitsPerSample,
bitsPerPixel,
bytesPerRow,
colorSpace,
CGBitmapFlags.ByteOrderDefault,
data,
decode: null,
shouldInterpolate: false,
intent: CGColorRenderingIntent.Default);
return cgImage;
}