LoginSignup
0
0

More than 5 years have passed since last update.

SFML.netで画像の色違いを表現するプログラム

Last updated at Posted at 2018-02-25

最初に

少し前に、SDL2で色変化プログラムを書いたのですが、
SFMLでも同じことできたらいいなと思って、
画像の色違いを表現するコードを考えてました

相変わらず説明下手ですがどうか

↓関連記事
【C# + SDL2】色調を用いて、画像の色違いを表現してみるサンプル
https://qiita.com/minion_cs_user/items/43147d3c6ff28cbbdf62

SFML.netを使ってみた
https://qiita.com/minion_cs_user/items/7ffe3b9042dc72152caf

コード全文

/*

レトロゲームでよくある、画像の色違いを表現する
プログラムです

コードはそんなに長くないけど、
一からこれ書くのは結構大変だね

このアルゴリズム、
SFMLの標準機能でついたりしないかな?

*/

using System;
using SFML.Graphics;
using System.IO;
using SFML.Window;
using System.Collections.Generic;

namespace TestProgram {
    sealed class Program {
        const string errorFilePath = "error.txt";

        public static Program Obj { get; } = new Program();

        static Random Random { get; } = new Random();

        static void Main() {
            try { Obj.Start(); }
            catch (Exception e) {
                File.WriteAllText(errorFilePath, e.Message);
                Console.WriteLine(e.Message);
            }
        }

        void Start() {
            var window = new RenderWindow(new VideoMode(300, 300), "", Styles.Close);
            window.Closed += (sender, e) => window.Close();
            window.SetFramerateLimit(60);

            //テクスチャ表示用スプライトを作成
            var normal = new Sprite(LoadTextureNormal());
            normal.Position = new SFML.System.Vector2f(20, 20);

            //色違いテクスチャ表示用スプライトを作成
            var custom = new Sprite(LoadTextureCustom());
            custom.Position = new SFML.System.Vector2f(120, 20);

            var group = new List<Sprite>();
            //分割されたテクスチャのグループを作成
            var group_textures = LoadTextureSplit();
            //分割されたテクスチャのグループを表示する際の色配列を作成
            var group_color_ary = new Color[group_textures.Length];
            for (var i = 0; i < group_color_ary.Length; i++) group_color_ary[i] = GetColorRandom();

            foreach (var i in group_textures) {
                var sprite = new Sprite(i);

                sprite.Position = new SFML.System.Vector2f(220, 20);

                group.Add(sprite);
            }

            while (window.IsOpen) { 
                window.DispatchEvents();
                window.Clear();

                //テクスチャを表示
                window.Draw(normal);
                //テクスチャの色違いを表示
                window.Draw(custom);

                for(var i = 0; i < group.Count; i++) {
                    //表示テスト用として、毎フレーム色を変える
                    group_color_ary[i].R++;

                    //分割されたテクスチャの表示色を指定
                    group[i].Color = group_color_ary[i];
                    //分割されたテクスチャを1つずつ表示
                    window.Draw(group[i]);
                }

                window.Display();
            }
        }

        static Color GetColorRandom() {
            var r = (byte)Random.Next(byte.MaxValue);
            var g = (byte)Random.Next(byte.MaxValue);
            var b = (byte)Random.Next(byte.MaxValue);

            return new Color(r, g, b);
        }

        //テクスチャを作成
        static Texture LoadTextureNormal() {
            return new Texture("test.png");
        }
        //テクスチャの色違いを作成
        static Texture LoadTextureCustom() {
            var image = new Image("test.png");

            var color_ary2d = new Color[image.Size.X, image.Size.Y];

            var old_colors = new List<Color>();
            var new_colors = new List<Color>();

            for (var i = 0; i < image.Size.X; i++) {
                for (var n = 0; n < image.Size.Y; n++) {
                    var color = image.GetPixel((uint)i, (uint)n);

                    if (!old_colors.Contains(color)) {
                        old_colors.Add(color);
                        new_colors.Add(GetColorRandom());
                    }

                    //テクスチャ作成用配列に色を指定
                    color_ary2d[i, n] = new_colors[old_colors.IndexOf(color)];
                }
            }

            //テクスチャ作成用配列からテクスチャを作成
            return new Texture(new Image(color_ary2d));
        }
        //テクスチャのパーツを分割
        static Texture[] LoadTextureSplit() {
            var image = new Image("test.png");

            var color_ary2d_list = new List<Color[,]>();

            var old_colors = new List<Color>();

            for (var i = 0; i < image.Size.X; i++) {
                for (var n = 0; n < image.Size.Y; n++) {
                    var color = image.GetPixel((uint)i, (uint)n);

                    if (!old_colors.Contains(color)) {
                        old_colors.Add(color);

                        color_ary2d_list.Add(new Color[image.Size.X, image.Size.Y]);
                    }

                    //テクスチャの表示部分は全て白にする
                    //(色調による色変化ができるため)
                    color_ary2d_list[old_colors.IndexOf(color)][i, n] = Color.White;
                }
            }

            var ary = new Texture[color_ary2d_list.Count];

            for(var i = 0; i < color_ary2d_list.Count; i++) {
                ////テクスチャ作成用配列からテクスチャを作成
                ary[i] = new Texture(new Image(color_ary2d_list[i]));
            }

            return ary;
        }
    }
}


最後に

これを一から書くなら
SFMLで書くよりSDL2で書くほうが楽なのかな?

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0