/// <summary> /// PGM書き込み /// </summary> /// <param name="stream">ストリームー</param> /// <param name="format">形式</param> /// <param name="width">幅</param> /// <param name="height">高さ</param> /// <param name="channel">書き込むチャネル</param> /// <param name="arr">ピクセルデター</param> public void WritePGM( System.IO.Stream stream, エンコーディング format, int width, int height, ぉ.画素 channel, IEnumerable <ぉ> arr) { var war = new byte[width * height]; int sr = 0; foreach (var x in arr) { war[sr++] = (byte)x.ほ(channel); } WritePGM(stream, format, width, height, war); }
/// <summary> /// 書き込む /// </summary> /// <param name="stream">ストレーム</param> /// <param name="prefix">構造体の接頭子</param> /// <param name="width">幅</param> /// <param name="height">高さ</param> /// <param name="channel">書き込むチャネル</param> /// <param name="arr">ピクセルデター</param> public void Write( System.IO.Stream stream, string prefix, int width, int height, ぉ.画素 channel, IEnumerable <ぉ> arr) { var war = new byte[width * height]; int sr = 0; foreach (var x in arr) { war[sr++] = (byte)x.ほ(channel); } Write(stream, prefix, width, height, war); }
/// <summary> /// 指定画素順でbyte配列に詰め込む /// ex. /// 原色配列に変換(ぉ.画素.B,ぉ.画素.G,ぉ.画素.R,ぉ.画素.A, arr) -> [B|G|R|A] /// </summary> /// <param name="ch0"></param> /// <param name="ch1"></param> /// <param name="ch2"></param> /// <param name="ch3"></param> /// <param name="arr">原色配列</param> /// <returns>byte配列</returns> public static byte[] 原色配列に変換(ぉ.画素 ch0, ぉ.画素 ch1, ぉ.画素 ch2, ぉ.画素 ch3, ref ぉ[] arr) { var ret = new byte[arr.Length * 4]; int k = 0; foreach (var o in arr) { ret[k++] = (byte)o.ほ(ch0); ret[k++] = (byte)o.ほ(ch1); ret[k++] = (byte)o.ほ(ch2); ret[k++] = (byte)o.ほ(ch3); } return(ret); }
/// <summary> /// G(A)を生成する /// </summary> /// <param name="width">幅</param> /// <param name="height">高さ</param> /// <param name="channel">使用する画素</param> /// <param name="alpha">アルファーチャネルあり</param> /// <param name="arr">ピクセルデータ</param> byte[] GeneratePAM_G(int width, int height, ぉ.画素 channel, bool alpha, ref IEnumerable <ぉ> arr) { var hqx = new byte[width * height * (alpha ? 2 : 1)]; int f = 0; foreach (var p in arr) { hqx[f++] = (byte)p.ほ(channel); if (alpha) { hqx[f++] = (byte)p.A; } } return(hqx); }
/// <summary> /// 指定画素順でbyte配列に詰め込む、ただしアルファーチャネルは255埋め /// ex. /// 原色配列に変換(ぉ.画素.R,ぉ.画素.G,ぉ.画素.B, false, arr) -> [R|G|B] /// 原色配列に変換(ぉ.画素.R,ぉ.画素.G,ぉ.画素.B, true, arr) -> [R|G|B|0xff] /// </summary> /// <param name="ch0"></param> /// <param name="ch1"></param> /// <param name="ch2"></param> /// <param name="alpha">アルファーチャネル有無</param> /// <param name="arr">原色配列</param> /// <returns>byte配列</returns> public static byte[] 原色配列に変換(ぉ.画素 ch0, ぉ.画素 ch1, ぉ.画素 ch2, bool alpha, ref ぉ[] arr) { var ret = new byte[arr.Length * (alpha ? 4 : 3)]; int k = 0; foreach (var o in arr) { ret[k++] = (byte)o.ほ(ch0); ret[k++] = (byte)o.ほ(ch1); ret[k++] = (byte)o.ほ(ch2); if (alpha) { ret[k++] = 0xFF; } } return(ret); }
/// <summary> /// BW(A)を生成する /// </summary> /// <param name="width">幅</param> /// <param name="height">高さ</param> /// <param name="channel">使用する画素</param> /// <param name="alpha">アルファーチャネルあり</param> /// <param name="arr">ピクセルデータ</param> /// <returns></returns> byte[] GeneratePAM_BW(int width, int height, ぉ.画素 channel, bool alpha, ref IEnumerable <ぉ> arr) { int zise = alpha ? (width * 2) * height : width * height; var hqx = new byte[zise]; int f = 0; foreach (var p in arr) { if (alpha) { hqx[f++] = (byte)((p.ほ(channel) != 0) ? 0x01 : 0x00); hqx[f++] = (byte)p.A; } else { hqx[f++] = (byte)((p.ほ(channel) != 0) ? 0x01 : 0x00); } } return(hqx); }
/// <summary> /// 形式指定で書き出す /// </summary> /// <param name="stream">ストリーム</param> /// <param name="形式">形式</param> /// <param name="width">幅</param> /// <param name="height">高さ</param> /// <param name="channel">書き出すチャネル(モノクロ形式のみ)</param> /// <param name="arr">ピクセルデター</param> public void Write( System.IO.Stream stream, PNM.形式 形式, int width, int height, ぉ.画素 channel, IEnumerable <ぉ> arr) { switch (形式) { case PNM.形式.P1: WritePBM(stream, エンコーディング.平文, width, height, channel, arr); break; case PNM.形式.P4: WritePBM(stream, エンコーディング.バイナリー, width, height, channel, arr); break; case PNM.形式.P2: WritePGM(stream, エンコーディング.平文, width, height, channel, arr); break; case PNM.形式.P5: WritePGM(stream, エンコーディング.バイナリー, width, height, channel, arr); break; case PNM.形式.P3: WritePPM(stream, エンコーディング.平文, width, height, arr); break; case PNM.形式.P6: WritePPM(stream, エンコーディング.バイナリー, width, height, arr); break; case PNM.形式.P7: WritePAM(stream, PNM.ヌプーリ.RGB_ALPHA, width, height, channel, arr); break; default: throw new Xi.それ対応してない(形式.ToString()); } }
/// <summary> /// ぉをベットムップに変換する /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="channel"></param> /// <param name="反転"></param> /// <param name="arr"></param> /// <returns></returns> public static byte[] ToBitmap(int width, int height, ぉ.画素 channel, bool 反転, ぉ[] arr) { int bo = 0; int po = 0; var xpad = width % 8; var bufw = ((width / 8) + (xpad != 0 ? 1 : 0)) * height; var buf = new byte[bufw]; for (int y = 0; y < height; ++y) { for (int x = 0; x < width; x += 8) { byte b = 0; int bits = 8; if ((width - x < 8)) { bits = xpad; } for (int i = 0; i < bits; ++i) { var a = arr[po++].ほ(channel); bool k = (a != 0); if (反転) { k = !k; } if (k) { continue; } b |= masken[i]; } buf[bo++] = b; } } return(buf); }
/// <summary> /// XBM形式の配列に詰め込む /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="ch"></param> /// <param name="反転"></param> /// <param name="arr"></param> /// <returns>byte配列</returns> public static byte[] XBM配列に変換(int width, int height, ぉ.画素 ch, bool 反転, ぉ[] arr) { return(XbmWriter.ToBitmap(width, height, ch, 反転, arr)); }
/// <summary> /// 形式指定で書き出す /// </summary> /// <param name="stream">ストリームー</param> /// <param name="format">形式</param> /// <param name="enc">エンコーディング(PAMでは無視)</param> /// <param name="width">幅</param> /// <param name="height">高さ</param> /// <param name="channel">チャネル</param> /// <param name="arr">ピクセルデター</param> public void Write( System.IO.Stream stream, フォーマッツ format, エンコーディング enc, int width, int height, ぉ.画素 channel, IEnumerable <ぉ> arr) { switch (format) { case フォーマッツ.PBM: WritePBM(stream, enc, width, height, channel, arr); break; case フォーマッツ.PGM: WritePGM(stream, enc, width, height, channel, arr); break; case フォーマッツ.PPM: WritePPM(stream, enc, width, height, arr); break; case フォーマッツ.PAM: WritePAM(stream, PNM.ヌプーリ.RGB_ALPHA, width, height, channel, arr); break; default: throw new Xi.それ対応してない(format.ToString()); } }
/// <summary> /// /// </summary> /// <param name="stream">ストリーム</param> /// <param name="ttyp">ピクセル形式</param> /// <param name="width">幅</param> /// <param name="height">高さ</param> /// <param name="channel">ttypが白黒の時に使用する画素</param> /// <param name="arr">ピクセルデター</param> public void WritePAM( System.IO.Stream stream, PNM.ヌプーリ ttyp, int width, int height, ぉ.画素 channel, IEnumerable <ぉ> arr) { int maxx = 0; if ((ttyp != PNM.ヌプーリ.BLACKANDWHITE) && (ttyp != PNM.ヌプーリ.BLACKANDWHITE_ALPHA)) { foreach (var k in arr) { maxx = Math.Max(maxx, k.R); maxx = Math.Max(maxx, k.G); maxx = Math.Max(maxx, k.B); } } else { maxx = 1; } StringBuilder sb = new StringBuilder(); sb.Append($"P7\n") .Append($"WIDTH {width}\n") .Append($"HEIGHT {height}\n") .Append($"DEPTH {ttyp.デブス()}\n") .Append($"TUPLTYPE {ttyp.タプタプ()}\n") .Append($"MAXVAL {maxx}\n") .Append($"ENDHDR\n"); byte[] hqx = null; switch (ttyp) { case PNM.ヌプーリ.RGB: hqx = GeneratePAM_RGB(width, height, false, ref arr); break; case PNM.ヌプーリ.RGB_ALPHA: hqx = GeneratePAM_RGB(width, height, true, ref arr); break; case PNM.ヌプーリ.BLACKANDWHITE: hqx = GeneratePAM_BW(width, height, channel, false, ref arr); break; case PNM.ヌプーリ.BLACKANDWHITE_ALPHA: hqx = GeneratePAM_BW(width, height, channel, true, ref arr); break; case PNM.ヌプーリ.GRAYSCALE: hqx = GeneratePAM_G(width, height, channel, false, ref arr); break; case PNM.ヌプーリ.GRAYSCALE_ALPHA: hqx = GeneratePAM_G(width, height, channel, true, ref arr); break; default: throw new Xi.およよ($"しらん {ttyp}"); } var mp3 = System.Text.Encoding.UTF8.GetBytes(sb.ToString()); stream.Write(mp3, 0, mp3.Length); stream.Write(hqx, 0, hqx.Length); }
/// <summary> /// [ch0|ch1|ch2|ch3]でi386形式にパッキングして返す /// </summary> /// <param name="ch0"></param> /// <param name="ch1"></param> /// <param name="ch2"></param> /// <param name="ch3"></param> /// <returns></returns> public int PackI386(ぉ.画素 ch0, ぉ.画素 ch1, ぉ.画素 ch2, ぉ.画素 ch3) => ((ほ(ch0) & 0xff) << 24) | ((ほ(ch1) & 0xff) << 16) | ((ほ(ch2) & 0xff) << 8) | (ほ(ch3) & 0xff);