Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.01.13;
Скачать: CL | DM;

Вниз

Искажение изображения.   Найти похожие ветки 

 
Sergey UNN   (2006-12-13 18:49) [0]

Здравствуйте, форумчане !
У меня возник следующий вопрос : имеется изображение bitmap, необходимо его исказить, то есть промасштабировать на разные значения по ширине и высоте (как я это понимаю). Для меня эта задача новая, не опытен я в таких делах, пользовался поиском, нашел несколько методов. один из них основывался на Stretchе bitmapa - результаты ужасающие, изображение совершенно неприемлемого качества, так же наткнулся на некую процедуру
DeleteScansRect
, вот код :
unit DeleteScans;
//Renate Schaaf  
//renates@xmission.com  

interface

uses Windows, Graphics;

procedure DeleteScansRect(Src, Dest: TBitmap; rs, rd: TRect);
//scanline implementation of Stretchblt/Delete_Scans  
//about twice as fast  
//Stretches Src to Dest, rs is source rect, rd is dest. rect  
//The stretch is centered, i.e the center of rs is mapped to the center of rd.  
//Src, Dest are assumed to be bottom up  

implementation

uses Classes, math;

type
TRGBArray = array[0..64000] of TRGBTriple;
PRGBArray = ^TRGBArray;

TQuadArray = array[0..64000] of TRGBQuad;
PQuadArray = ^TQuadArray;

procedure DeleteScansRect(Src, Dest: TBitmap; rs, rd: TRect);
var
 xsteps, ysteps: array of Integer;
intscale: Integer;
i, x, y, x1, x2, bitspp, bytespp: Integer;
ts, td: PByte;
bs, bd, WS, hs, w, h: Integer;
Rows, rowd: PByte;
j, c: Integer;
pf: TPixelFormat;
xshift, yshift: Integer;
begin
WS := rs.Right - rs.Left;
hs := rs.Bottom - rs.Top;
w := rd.Right - rd.Left;
h := rd.Bottom - rd.Top;
pf := Src.PixelFormat;
if (pf <> pf32Bit) and (pf <> pf24bit) then
begin
pf := pf24bit;
Src.PixelFormat := pf;
end;
Dest.PixelFormat := pf;
if not (((w <= WS) and (h <= hs)) or ((w >= WS) and (h >= hs))) then
//we do not handle a mix of up-and downscaling,  
//using threadsafe StretchBlt instead.  
begin
Src.Canvas.Lock;
Dest.Canvas.Lock;
try
 SetStretchBltMode(Dest.Canvas.Handle, STRETCH_DELETESCANS);
 StretchBlt(Dest.Canvas.Handle, rd.Left, rd.Top, w, h,
 Src.Canvas.Handle, rs.Left, rs.Top, WS, hs, SRCCopy);
finally
 Dest.Canvas.Unlock;
 Src.Canvas.Unlock;
end;
Exit;
end;

if pf = pf24bit then
begin
bitspp := 24;
bytespp := 3;
end
else
begin
bitspp := 32;
bytespp := 4;
end;
bs := (Src.Width * bitspp + 31) and not 31;
bs := bs div 8; //BytesPerScanline Source  
bd := (Dest.Width * bitspp + 31) and not 31;
bd := bd div 8; //BytesPerScanline Dest  
if w < WS then //downsample  
begin
//first make arrays of the skipsteps  
 SetLength(xsteps, w);
SetLength(ysteps, h);
intscale := round(WS / w * $10000);
x1  := 0;
x2  := (intscale + $7FFF) shr 16;
c := 0;
for i := 0 to w - 1 do
begin
 xsteps[i] := (x2 - x1) * bytespp;
 x1  := x2;
 x2  := ((i + 2) * intscale + $7FFF) shr 16;
 if i = w - 2 then
 c := x1;
end;
xshift := min(max((WS - c) div 2, - rs.Left), Src.Width - rs.Right);
intscale := round(hs / h * $10000);
x1  := 0;
x2  := (intscale + $7FFF) shr 16;
c  := 0;
for i := 0 to h - 1 do
begin
 ysteps[i] := (x2 - x1) * bs;
 x1  := x2;
 x2  := ((i + 2) * intscale + $7FFF) shr 16;
 if i = h - 2 then
 c := x1;
end;
yshift := min(max((hs - c) div 2, - rs.Top), Src.Height - rs.Bottom);
if pf = pf24bit then
begin
 Rows := @PRGBArray(Src.Scanline[rs.Top + yshift])^[rs.Left + xshift];
 rowd := @PRGBArray(Dest.Scanline[rd.Top])^[rd.Left];
 for y := 0 to h - 1 do
 begin
 ts := Rows;
 td := rowd;
 for x := 0 to w - 1 do
 begin
 pRGBTriple(td)^ := pRGBTriple(ts)^;
 Inc(td, bytespp);
 Inc(ts, xsteps[x]);
 end;
 Dec(rowd, bd);
 Dec(Rows, ysteps[y]);
 end;
end
else
begin
 Rows := @PQuadArray(Src.Scanline[rs.Top + yshift])^[rs.Left + xshift];
 rowd := @PQuadArray(Dest.Scanline[rd.Top])^[rd.Left];
 for y := 0 to h - 1 do
 begin
 ts := Rows;
 td := rowd;
 for x := 0 to w - 1 do
 begin
 pRGBQuad(td)^ := pRGBQuad(ts)^;
 Inc(td, bytespp);
 Inc(ts, xsteps[x]);
 end;
 Dec(rowd, bd);
 Dec(Rows, ysteps[y]);
 end;
end;
end
else
begin
//first make arrays of the steps of uniform pixels  
 SetLength(xsteps, WS);
SetLength(ysteps, hs);
intscale := round(w / WS * $10000);
x1  := 0;
x2  := (intscale + $7FFF) shr 16;
c  := 0;
for i := 0 to WS - 1 do
begin
 xsteps[i] := x2 - x1;
 x1  := x2;
 x2  := ((i + 2) * intscale + $7FFF) shr 16;
 if x2 > w then
 x2 := w;
 if i = WS - 1 then
 c := x1;
end;
if c < w then //>is now not possible  
 begin
 xshift  := (w - c) div 2;
 yshift  := w - c - xshift;
 xsteps[WS - 1] := xsteps[WS - 1] + xshift;
 xsteps[0] := xsteps[0] + yshift;
end;
intscale := round(h / hs * $10000);
x1  := 0;
x2  := (intscale + $7FFF) shr 16;
c  := 0;
for i := 0 to hs - 1 do
begin
 ysteps[i] := (x2 - x1);
 x1  := x2;
 x2  := ((i + 2) * intscale + $7FFF) shr 16;
 if x2 > h then
 x2 := h;
 if i = hs - 1 then
 c := x1;
end;
if c < h then
begin
 yshift  := (h - c) div 2;
 ysteps[hs - 1] := ysteps[hs - 1] + yshift;
 yshift  := h - c - yshift;
 ysteps[0] := ysteps[0] + yshift;
end;
if pf = pf24bit then
begin
 Rows := @PRGBArray(Src.Scanline[rs.Top])^[rs.Left];
 rowd := @PRGBArray(Dest.Scanline[rd.Top])^[rd.Left];
 for y := 0 to hs - 1 do
 begin
 for j := 1 to ysteps[y] do
 begin
 ts := Rows;
 td := rowd;
 for x := 0 to WS - 1 do
 begin
  for i := 1 to xsteps[x] do
  begin
  pRGBTriple(td)^ := pRGBTriple(ts)^;
  Inc(td, bytespp);
  end;
  Inc(ts, bytespp);
 end;
 Dec(rowd, bd);
 end;
 Dec(Rows, bs);
 end;
end
else
begin
 Rows := @PQuadArray(Src.Scanline[rs.Top])^[rs.Left];
 rowd := @PQuadArray(Dest.Scanline[rd.Top])^[rd.Left];
 for y := 0 to hs - 1 do
 begin
 for j := 1 to ysteps[y] do
 begin
 ts := Rows;
 td := rowd;
 for x := 0 to WS - 1 do
 begin
  for i := 1 to xsteps[x] do
  begin
  pRGBQuad(td)^ := pRGBQuad(ts)^;
  Inc(td, bytespp);
  end;
  Inc(ts, bytespp);
 end;
 Dec(rowd, bd);
 end;
 Dec(Rows, bs);
 end;
end;
end;
end;


end.


однако воспользоватся не смог, выдает ошибку, пробовал разные варианты кода, поэтому приводить их сюда я не посчитал нужным, посему прошу опытных программистов помочь с примером использования (входных данных) и вообще точно разъяснить значения параметров r1 и r2. В англ. я видимо не особо силен - разобратся сам не смог.

Заранее большое спасибо, рассчитываю на понимание.


 
antonn ©   (2006-12-13 21:26) [1]


> посему прошу опытных программистов помочь с примером
> использования (входных данных) и вообще точно
> разъяснить значения параметров r1 и r2. В англ. я
> видимо не особо силен - разобратся сам не смог.

может просто скажете, что вам нужно получить в результате?


 
Sergey UNN   (2006-12-14 04:39) [2]


> Здравствуйте, форумчане !
> У меня возник следующий вопрос : имеется изображение bitmap,
>  необходимо его исказить, то есть промасштабировать на разные
> значения по ширине и высоте (как я это понимаю). Для меня
> эта задача новая, не опытен я в таких делах, пользовался
> поиском, нашел несколько методов. один из них основывался
> на Stretchе bitmapa - результаты ужасающие, изображение
> совершенно неприемлемого качества, так же наткнулся на некую
> процедуру

Мне нужно исказить изображение.


 
Думкин ©   (2006-12-14 08:38) [3]

> Sergey UNN   (14.12.06 04:39) [2]

Исказить или поменять размер?
StretchBlt HALFTONE


 
Stexen ©   (2006-12-16 04:53) [4]

ого, исходничек, как я понял исказить, это просто изменить размер не пропорционально???По-моему
> Думкин ©   (14.12.06 08:38) [3]
прав тут StretchBlt достаточно будет...


> наткнулся на некую процедуру
> DeleteScansRect

Почему то мне кажется что я тоже на нее натыкался давным давно...

А вообще зачем такие исходники кидать, если все равно наверняка никто не вчитывался...

Тебе нужны фильтры для масштабирования, если качество не устраивает при StretchBlt. У меня где то валялась библиотека, реализующая несколько фильров, если надо могу скинуть...
А вообще посмотри g32, там всего два алгоритма, но очень быстрые, хорошо реализованы.


 
Сотрудник деканата   (2007-02-28 17:40) [5]

Исказить можно огромным количеством методов.



Страницы: 1 вся ветка

Текущий архив: 2008.01.13;
Скачать: CL | DM;

Наверх




Память: 0.49 MB
Время: 0.016 c
2-1197373127
@!!ex
2007-12-11 14:38
2008.01.13
Фиксация углов куба.


11-1176486000
Vladimir Kladov
2007-04-13 21:40
2008.01.13
Версия 2.57


2-1197385221
Tant
2007-12-11 18:00
2008.01.13
Описать процедуру ADDT(T,C)


3-1189165817
keymaster
2007-09-07 15:50
2008.01.13
Как получить из oracle refcursor (ADO)


2-1197845685
bpeguk
2007-12-17 01:54
2008.01.13
Элипс