3

次のような、画像をセピアトーンバージョンに変換するための奇妙なルーチンを見てきました。

function bmptosepia(const bmp: TBitmap; depth: Integer): Boolean;
var
color,color2:longint;
r,g,b,rr,gg:byte;
h,w:integer;
begin
  for h := 0 to bmp.height do
  begin
    for w := 0 to bmp.width do
    begin
//first convert the bitmap to greyscale
    color:=colortorgb(bmp.Canvas.pixels[w,h]);
    r:=getrvalue(color);
    g:=getgvalue(color);
    b:=getbvalue(color);
    color2:=(r+g+b) div 3;
    bmp.canvas.Pixels[w,h]:=RGB(color2,color2,color2);
//then convert it to sepia
    color:=colortorgb(bmp.Canvas.pixels[w,h]);
    r:=getrvalue(color);
    g:=getgvalue(color);
    b:=getbvalue(color);
    rr:=r+(depth*2);
    gg:=g+depth;
    if rr <= ((depth*2)-1) then
    rr:=255;
    if gg <= (depth-1) then
    gg:=255;
    bmp.canvas.Pixels[w,h]:=RGB(rr,gg,b);
    end;
  end;
end;

ここから)しかし、私は任意の色に対してこれを行う何かが必要です-つまり、画像を取得し、おそらくそのグレースケールバージョンを形成してから、新しい色を画像に適用します。これは私が問題を抱えている最後のビットです-つまり、灰色の色合いを目的の色に置き換えることです。

だから私は必要です

procedure BmpToOneColor (const bmp      : TBitmap ;
                               depth    : Integer ; 
                               NewColor : TColor) ;

(オリジナルがブール関数として書かれた理由はわかりません)。

4

1 に答える 1

3

基本アルゴリズムは、グレー値の各カラーチャネルに固定オフセットを追加するだけです。これを一般化して、NewColorパラメーターが各チャネルのオフセットを決定するようにすることができます。depthこれは冗長になり、完全に省略できることに注意してください。

rbase:=getrvalue(NewColor);
gbase:=getgvalue(NewColor);
bbase:=getbvalue(NewColor);
base:=min(rbase,min(gbase,bbase));
rdepth:=rbase-base;
gdepth:=gbase-base;
bdepth:=bbase-base;

rr:=r+rdepth;
gg:=g+gdepth;
bb:=b+bdepth;
if rr < rdepth then
    rr:=255;
if gg < gdepth then
    gg:=255;
if bb < bdepth then
    bb:=255;
于 2012-11-20T22:36:26.387 に答える