2012-11-20 3 views
3

임의의 색상 "세피아"루틴의 구현 :델파이 -이처럼 세피아 톤 버전으로 이미지를 변환하는 이상한 루틴을 본 적이

( here에서)
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) ; 

(I 원래는 부울 함수로 기록 된 이유를 몰라)

이 필요합니다.

+1

사용 ['ScanLine' (http://docwiki.embarcadero.com/Libraries/XE2/en/Vcl.Graphics.TBitmap.ScanLine) 대신 ['Pixels']의 (HTTP//docwiki.embarcadero.com/Libraries/XE3/en/Vcl.Graphics.TCustomCanvas.Pixels). Latter는 더 많은 픽셀로 작업 할 때 매우 비효율적입니다. – TLama

답변

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; 
관련 문제