2006年02月08日
川俣晶の縁側ソフトウェア技術雑記total 6660 count

.NET Frameworkクラスライブラリを用いてビットマップの明るさを変える

Written By: 川俣 晶連絡先

 現在書いているプログラム(近日公開)で、画面キャプチャした画像を表示する際、そのまま表示すると本物の画面と紛らわしいので、明るさを落として表示させたいと思いました。

 しかし、軽く検索してみても、ビットマップの明るさを変える方法が分かりませんでした。

 見つかったのは、直接バイト単位でデータを書き換えるようなサンプルだけ。それはちょっと勘弁……と思って一時は挫折しかかったのですが。

 正攻法でMSDNの目次から読んでいるうちに、やっと分かりました。

 結論的に言えば、ビットマップの明るさを変える機能は存在しないようですが、それよりも遙かに強力な「行列による色変換」の機能が備わっています。

 これさえあれば、大抵の色変換は一発で実行できます。

 しかも、paintイベントで実行しても良いぐらいの軽さです。

 というわけで、テストプログラムを作成してみました。

実行結果 §

実行結果

 上が加工前。

 下が加工後。

 赤、青、緑、黄色のいずれも色が変化せず、明るさだけ変わっていることを確認してください。

ソースコード §

 Visual Studio 2005のC#によるWindowsアプリケーションのプロジェクト。

 フォーム上に2枚のPictureBoxを貼り付けています。

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Drawing.Imaging;

using System.Text;

using System.Windows.Forms;

namespace DarkenBitmap

{

    public partial class Form1 : Form

    {

        public Form1()

        {

            InitializeComponent();

        }

        private Image image;

        private void Form1_Load(object sender, EventArgs e)

        {

            image = new Bitmap(@"s:\test.jpg");

            this.pictureBox1.Image = image;

        }

        private void pictureBox2_Paint(object sender, PaintEventArgs e)

        {

            ImageAttributes imageAttributes = new ImageAttributes();

            int width = image.Width;

            int height = image.Height;

            float[][] colorMatrixElements = { 

                new float[] {0.5f, 0,    0,    0, 0},

                new float[] {0,    0.5f, 0,    0, 0},

                new float[] {0,    0,    0.5f, 0, 0},

                new float[] {0,    0,    0,    1, 0},

                new float[] {0,    0,    0,    0, 1}};

            ColorMatrix colorMatrix = new ColorMatrix(colorMatrixElements);

            imageAttributes.SetColorMatrix(

               colorMatrix,

               ColorMatrixFlag.Default,

               ColorAdjustType.Bitmap);

            e.Graphics.DrawImage(

               image,

               new Rectangle(0, 0, width, height),  // destination rectangle 

               0, 0,        // upper-left corner of source rectangle 

               width,       // width of source rectangle

               height,      // height of source rectangle

               GraphicsUnit.Pixel,

               imageAttributes);

        }

    }

}

感想 §

 久々に、感動ものの機能です。

 ずっと昔、OS/2のPresentation ManagerのAPIを見ていて、座標の変換を行列で指定可能なのを見たのに匹敵する感動かな?(既に記憶があやふやなので確かではないかも) 当時のWindows 2.x~3.0の座標系は縦横のスケーリングはできても、行列指定などという「自由度は高いが真面目に実装するとやたCPUパワーを食いそうな」機能は持っていなかったので。

 こんな感動が眠っているとは、MSDNのまだ見ていないページを他にもいろいろ読んでいきたいですね。

Facebook

キーワード【 川俣晶の縁側ソフトウェア技術雑記
【技術雑記】の次のコンテンツ
2006年
02月
14日
PDFドライバとの関係で考える・GDIは1ピクセルよりも細い線を扱えないのか!?
3days 0 count
total 7897 count
【技術雑記】の前のコンテンツ
2006年
02月
06日
ソフト冒険記「OKS Samplers」 トピックマップとオントロジで遊ぼう
3days 0 count
total 5838 count

このコンテンツを書いた川俣 晶へメッセージを送る

[メッセージ送信フォームを利用する]

メッセージ送信フォームを利用することで、川俣 晶に対してメッセージを送ることができます。

この機能は、100%確実に川俣 晶へメッセージを伝達するものではなく、また、確実に川俣 晶よりの返事を得られるものではないことにご注意ください。

このコンテンツへトラックバックするためのURL

https://mag.autumn.org/tb.aspx/20060208182549
サイトの表紙【技術雑記】の表紙【技術雑記】のコンテンツ全リスト 【技術雑記】の入手全リスト 【技術雑記】のRSS1.0形式の情報このサイトの全キーワードリスト 印刷用ページ

管理者: 川俣 晶連絡先

Powered by MagSite2 Version 0.36 (Alpha-Test) Copyright (c) 2004-2021 Pie Dey.Co.,Ltd.