![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Stretch с помощью FastDIB [D7, 2003]
Fox © (2014-09-20 14:38:00)Здравствуйте!
Есть код, который позволяет качественно изменять размеры PNG-картинки с помощью FastDIB, но только с потерей прозрачности. Подскажите как его можно изменить, чтобы поддерживалась прозрачность и полупрозрачность. Заранее спасибо!
uses PNGImage, FastDIB, FastSize;
Procedure DrawMy(X,Y:Integer;DrIn:TPNGObject;DrOut:TImage;W,H:Integer);
Var TB:TBitmap;
BMP1: TFastDIB;
BMP2: TFastDIB;
begin
BMP1 := TFastDIB.Create;
BMP2 := TFastDIB.Create;
TB := TBitmap.Create;
TB.Width :=DrIn.Width;
TB.Height:=DrIn.Height;
TB.Canvas.Draw(0,0,DrIn);
TB.PixelFormat:=pf24bit;
BMP1.LoadFromHandle(TB.Handle);
BMP2.SetSize(W,H,24);
SmoothResize24(BMP1,BMP2,rfSpline3);
BMP2.Draw(DrOut.Canvas.Handle, X, Y);
BMP1.Free;
BMP2.Free;
TB.Free;
end;
Rouse_ (2014-09-20 22:08:00) [1]с
function TFWCustomIconEx.GetBitmapInfoначинай смотреть
Rouse_ (2014-09-20 22:06:00) [2]Ого, действительно сильно хуже... но так быть не должно.
Вот здесь я работаю с данными в PNG формате у иконок, содержащих изображения размером 256 на 256 пикселей: http://rouse.drkb.ru/components.php#fwiconex
Таких артефактов точно не наблюдается.
Обрати внимание на вызовы функций и их параметры, вполне возможно что у тебя что-то напутано.
Fox (2014-09-20 22:04:00) [3]>Rouse_
С GetThumbnailImage не лучше.
>junglecat
Поигрался. Пока результат не лучше.
junglecat (2014-09-20 21:58:00) [4]я бы поигрался с TGPGraphics.SetInterpolationMode / SetSmoothingMode
Fox (2014-09-20 21:53:00) [5]Вот код:
GdipSetInterpolationMode(Graph, InterpolationModeHighQualityBicubic);
Graph.DrawImage(in_img, MakeRect(0, 0, 105, 105), 0, 0, 256, 256, UnitPixel);
Сверху рисунок на GDI+, снизу - FastDIB. Ну сильно хуже на GDI+!!!
http://www.dizaak.narod.ru/test.png
Rouse_ (2014-09-20 21:48:00) [6]Ну и вообще все из папки "Using Images, Bitmaps, and Metafiles"
Rouse_ (2014-09-20 21:47:00) [7]Вот этот пример смотрел?
...\gdiplus\demos\Using Images, Bitmaps, and Metafiles\Creating Thumbnail Images\
junglecat (2014-09-20 21:41:00) [8]> Качество изменения размера GDI+ гораздо хуже FastDIB
GdipSetInterpolationMode?
Fox (2014-09-20 21:33:00) [9]Качество изменения размера GDI+ гораздо хуже FastDIB. Если конечно нет других вариантов:
Graph.DrawImage(in_img, MakeRect(0, 0, 105, 105), 0, 0, 256, 256, UnitPixel);
Fox (2014-09-20 20:39:00) [10]Буду разбираться, спасибо!
Rouse_ (2014-09-20 20:22:00) [11]Не нашел оригинала, откуда качал - поэтому выкладываю сам архив, там все найдется: http://rouse.drkb.ru/tmp/gdiplus.zip
Fox (2014-09-20 20:11:00) [12]Возможно, GDI+ выход, нельзя ли привести пример кода с загрузкой 32-битного PNG из ресурса, качественного изменения размера и вывода куда-нибудь? Был бы очень признателен.
Rouse_ (2014-09-20 20:02:00) [13]ЗЫ: Я не говорю что оба этих фреймфорка нельзя совместить (вероятно как-то можно) просто ранее я с ними работал и из-за энного количества неудобств для меня, от FastDIB отказался в пользу GDI+
Rouse_ (2014-09-20 19:59:00) [14]Ну где происходит потеря альфаканала теперь в принципе понятна, не понятно что бы тебе хорошее посоветовать чтобы было для тебя удобно.
Вариант использования GDI++, вместо FastDIB и PNGImage не рассматривается?
Fox (2014-09-20 19:43:00) [15]Что-то вообще ничего не рисуется теперь...
invis (2014-09-20 19:30:00) [16]Ну я и не говорил, что только в этом проблема.
Ещё в этих местах альфа может теряться:
1) BMP1.LoadFromHandle(TB.Handle);
2) BMP2.Draw(DrOut.Canvas.Handle, X, Y);
поскольку это GDI, а у GDI с альфой вообще плохо.
Можно сделать так:
function CreateFDIBRef(b : TBitmap): TFastDIB;
Const pf : array[TPixelFormat] of Integer =
(0, 1, 4, 8, 16, 16, 24, 32, 0);
Var cm : TFColor;
begin
b.HandleType := bmDIB;
Result := TFastDIB.Create;
Case b.PixelFormat of
pf15bit : cm := FRGB(5,5,5);
pf16bit : cm := FRGB(5,6,5);
else cm := tfBlack;
end;
Result.SetInterface(b.ScanLine[b.Height-1], b.Width, b.Height, pf[b.PixelFormat],
cm.r, cm.g, cm.b);
If (Result.Bpp <= 8) and (b.Palette <> 0) then
GetPaletteEntries(b.Palette, 0, (1 shl Result.Bpp), Result.Colors^);
end;
Procedure DrawMy(X,Y:Integer;DrIn:TPNGObject;DrOut:TImage;W,H:Integer);
<...>
With DrOut.Picture.Bitmap do begin
PixelFormat := pf32bit;
Width := W; Height := h;
end;
Bmp1 := CreateFDIBRef(TB);
Bmp2 := CreateFDIBRef(DrOut.Picture.Bitmap);
SmoothResize32(BMP1,BMP2,rfSpline3);
Bmp2.Free;
Bmp1.Free;
<...>
Fox (2014-09-20 19:24:00) [17]
procedure ConvertPngToBitmap(inpng:tpngobject;var outbitmap:tbitmap);
const MaxPixelCountA=32000;
type TRGBAArray = array[0..MaxPixelCountA-1] of TRGBQuad;
PRGBAArray = ^TRGBAArray;
var rgb:prgbaarray;alp:pbytearray;i,j:integer;
begin
outbitmap:=tbitmap.create;
outbitmap.assign(inpng);
outbitmap.pixelformat:=pf32bit;
for i:=0 to outbitmap.height-1 do begin
rgb:=outbitmap.scanline[i];
alp:=inpng.alphascanline[i];
for j:=0 to outbitmap.width-1 do
rgb[j].rgbreserved:=alp[j];
end;
end;
Procedure DrawMy(X,Y:Integer;DrIn:TPNGObject;DrOut:TImage;W,H:Integer);
Var TB:TBitmap;
BMP1: TFastDIB;
BMP2: TFastDIB;
c:TFColor;
i,j:Integer;
begin
BMP1 := TFastDIB.Create;
BMP2 := TFastDIB.Create;
BMP2.SetTransparent(True);
TB := TBitmap.Create;
TB.Width :=DrIn.Width;
TB.Height:=DrIn.Height;
TB.PixelFormat:=pf32bit;
ConvertPngToBitmap(DrIn,TB);
BMP1.LoadFromHandle(TB.Handle);
BMP2.SetSize(W,H,32);
SmoothResize32(BMP1,BMP2,rfSpline3);
BMP2.Draw(DrOut.Canvas.Handle, X, Y);
BMP1.Free;
BMP2.Free;
TB.Free;
end;
Не помогло.
Fox (2014-09-20 19:08:00) [18]http://www.dizaak.narod.ru/-PNGImage.rar
invis (2014-09-20 19:07:00) [19]TPngImage.Draw, как я понял, не умеет выдавать альфа-канал "как есть", надо копировать его вручную через AlphaScanline.
Rouse_ (2014-09-20 19:00:00) [20]pngimage кидай