「Xamarin.Macで画素配列からCGImageを生成する」の版間の差分
ナビゲーションに移動
検索に移動
imported>Administrator (→RGB画像) |
imported>Administrator (→RGB画像) |
||
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の画像は正常にデコードできたようだ。 | ||
+ | <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> | ||
2017年8月21日 (月) 07:38時点における版
勉強がてら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の画像は正常にデコードできたようだ。
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;
}