ガンマ補正を写真画像に適用させる(VCL) ~Delphiでお手軽プログラミング

ガンマ補正を写真画像に適用させる(VCL) ~Delphiでお手軽プログラミング

(参考)バイキュービック法(bicubic)で拡大縮小する(VCL)
(参考)バイキュービック法(bicubic)で拡大縮小する(FMX)
(参考)バイラテラルフィルタ(bilateral filter)で美肌に加工(VCL)
(参考)バイラテラルフィルタ(bilateral filter)で美肌に加工(FMX)
(参考)ガンマ(gamma)補正を画像に適用する(FMX)
(参考)ソーベルフィルタ(Sobel filter)で境界(エッジ)検出(VCL)

ガンマ補正を使用する為のファイルの準備

本ページの下部のソースコードをコピーして「UMamGamma.pas」ファイルを作成し、 プロジェクトフォルダ内に入れる。

プロジェクトの作成とソースコードの記述

プロジェクトを新規作成(VCLアプリケーション)し、フォーム(Form1)にTImageを2個、TButtonを1個配置する。
Image1のPictureプロパティから、バイラテラルフィルタを適用したい画像をロードしておく。
TButton1をダブルクリックして、以下ソースコードを記述する。
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
  Vcl.StdCtrls, Vcl.ExtCtrls,
  Vcl.Imaging.jpeg, Vcl.Imaging.pngimage;

type
  TForm1 = class(TForm)
    Image1: TImage;
    Image2: TImage;
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

uses UMamGamma;

procedure TForm1.Button1Click(Sender: TObject);
var bmp:TBitmap;
begin
  bmp:=TBitmap.Create;
  try
    bmp.Assign(Image1.Picture.Graphic);
    MamGamma(bmp, Image2.Picture.Bitmap,0.6);
  finally
    bmp.Free;
  end;
end;

end.

実行する

実行ボタンを押して実行します。(デバッグ実行でもOK)

Button1をクリックすると、Image1画像にガンマ補正が適用された画像をImage2に表示します。

「UMamGamma.pas」ファイルのソースコード

unit UMamGamma;

interface
uses Vcl.Graphics,System.Math;

//Strength:強さ  0.0[暗]~1.0[何もしない]~10[明]
procedure MamGamma(source,dest:TBitmap;Strength:Extended);

implementation

procedure MamGamma(source,dest:TBitmap;Strength:Extended);
type
  TRGB =record B,G,R:byte; end;
  TRGBArr=array[0..32767] of TRGB;
  PRGBArr=^TRGBArr;
  TRGBArrArr=array[0..32767] of PRGBArr;
var x,y:Integer;
    SrcRGB,DestRGB:PRGBArr;
    ChangedCol:array[0..255] of Byte;
begin
  if not Assigned(source) then exit;
  if (source.Width=0) or (source.Height=0) then exit;
  if not Assigned(dest) then
    dest:=TBitmap.Create;

  if Strength<0 then Strength:=0;
  if Strength>10 then Strength:=10;

  if Strength=1 then
  begin
    dest.Assign(source);
    exit;
  end;

  source.PixelFormat:=pf24bit;
  dest.PixelFormat:=pf24bit;
  dest.Width:=source.Width;
  dest.Height:=source.Height;

  for x:=0 to 255 do
  begin
    ChangedCol[x]:=Round(255*Power(x/255,1/Strength));
  end;

  for y := 0 to source.Height-1 do
  begin
    SrcRGB:=source.ScanLine[y];
    DestRGB:=dest.ScanLine[y];
    for x := 0 to source.Width-1 do
    begin
      DestRGB[x].R:=ChangedCol[SrcRGB[x].R];
      DestRGB[x].G:=ChangedCol[SrcRGB[x].G];
      DestRGB[x].B:=ChangedCol[SrcRGB[x].B];
    end;
  end;
end;

end.