掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
imageの画像を縮小するときれいに描画されない。 (ID:10736)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
おはようございます。 Strechは単純間引きなので、斜め線がギザギザしたり、モアレっぽくなったりしますね。 (画像に限りませんが) 例え単純間引きを止めて、ある程度のタップ数で補間しても縮小サンプリングは「折り返し」という現象が発生し、モアレ状のパターンが生じることがあります。 従って縮小する前にローパスフィルタによって帯域制限をかけるのが普通です。 しかしながら、一般的な用途(サムネイル表示とか)であれば、ローパスフィルタは端折っても、まあ大丈夫ではないでしょうか。 縮小なら補間も線形補間で十分かと。 この場合、原理的には水平のみ縮小→垂直のみ縮小でOKです。 以下に単純な例を挙げます。(例ですので、速度・効率とかは考えていません) //---------------------------------------------------- type節に TRGBTripleArray = array[0 .. High(Integer) div 3 - 1] of RGBTRIPLE; PRGBTripleArray = ^TRGBTripleArray; //配列型のポインタ を追加、 button1、edit1、image1、image2を貼り付けて、FormCreate等で Image1 に既にbmpが読み込まれているものとします。 edit1に倍率(0.667とか)を入力しボタンを押すとimage2に縮小画像を表示します。 なお、デバッグは適当なので、倍率が2以上でエラーになっちゃいます^^; //--------------------------------------------------- procedure TForm1.Button1Click(Sender: TObject); var Ps,Ps2,Pd: PRGBTripleArray; HBMP,VBMP : TBitMap; xk,yk,rate : double; xphase,yphase : double; xdsize,ydsize :Integer; x,y :Integer; R0,G0,B0 :Short; R1,G1,B1 :Short; begin rate := StrToFloat(Edit1.Text); HBMP := TBitMap.Create; VBMP := TBitMap.Create; HBMP.PixelFormat := pf24bit; VBMP.PixelFormat := pf24bit; xdsize:=round(Image1.Picture.Bitmap.Width * rate); ydsize:=round(Image1.Picture.Bitmap.Height* rate); HBMP.Width := xdsize; HBMP.Height := Image1.Picture.Bitmap.Height; VBMP.Width := xdsize; VBMP.Height := ydsize; //水平のみ処理 for y := 0 to Image1.Picture.Bitmap.Height-1 do begin Ps := Image1.Picture.Bitmap.ScanLine[y]; Pd := HBMP.ScanLine[y]; xk := 0; x := 0; while (x < xdsize-1 )do begin xphase := xk - Trunc(xk); R0 := Ps[Trunc(xk)].rgbtRed; G0 := Ps[Trunc(xk)].rgbtGreen; B0 := Ps[Trunc(xk)].rgbtBlue; R1 := Ps[Trunc(xk)+1].rgbtRed; G1 := Ps[Trunc(xk)+1].rgbtGreen; B1 := Ps[Trunc(xk)+1].rgbtBlue; Pd[x].rgbtRed := Trunc(R0*(1-xphase) +R1*xphase); Pd[x].rgbtGreen:= Trunc(G0*(1-xphase) +G1*xphase); Pd[x].rgbtBlue := Trunc(B0*(1-xphase) +B1*xphase); xk := xk + 1/rate; Inc(x); end; end; //Image2.Picture.Bitmap.Assign(HBMP); //垂直のみ処理 yk :=0; y :=0; while ( y < ydsize-1) do begin yphase := yk - Trunc(yk); Ps := HBMP.ScanLine[Trunc(yk)]; Ps2:= HBMP.ScanLine[Trunc(yk)+1]; Pd := VBMP.ScanLine[y]; for x := 0 to xdsize-1 do begin R0 := Ps[x].rgbtRed; G0 := Ps[x].rgbtGreen; B0 := Ps[x].rgbtBlue; R1 := Ps2[x].rgbtRed; G1 := Ps2[x].rgbtGreen; B1 := Ps2[x].rgbtBlue; Pd[x].rgbtRed := Trunc(R0*(1-yphase) +R1*yphase); Pd[x].rgbtGreen:= Trunc(G0*(1-yphase) +G1*yphase); Pd[x].rgbtBlue := Trunc(B0*(1-yphase) +B1*yphase); end; yk := yk +1/rate; Inc(y); end; Image2.Picture.Bitmap.Assign(VBMP); HBMP.free; VBMP.free; end;
←解決時は質問者本人がここをチェックしてください。
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.