![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Прозрачний PNG
SIV5000 © (2010-09-06 13:19:00)Народ привет. Подскажите пожалуйста как создать чистый TPngObject. Под "чистым" имею в виду прозрачный а не заполненый каким то цветом, чтоб потом рисовать другие png на его канве. Например в Photoshop-е можно создать чистый документ с прозрачным фоном а потом рисовать на нем.
Пробую так:
создаю один TPngObject чтоб загрузить картинку
PN:=TPngObject.Create;
PN.LoadFromFile('test.png');
создаю чистый TPngObject и рисую на его канве первый TPngObject
png := tpngobject.createblank(COLOR_RGBALPHA, 16, 150, 150);
png.Canvas.Draw(0,0,PN);
в результате выходит первая картинка на черном фоне.
Вобще что хочу сделать: вод допустим есть такая програма ObjectDock, для фона она использует .png картинку малого размера а потом растягивеет ее но по регионах. Тоесть, допустим, левый участок и правый остаються такимы же (с закругленными углами и т.п.) а растягиваеться только средний участок. Нужно сделать то же самое.
Так вот думаю сделать ето так:
1. Создать чистый TPngObject (при создании формы) уже нужного размера.
2. Нарисовать левый и правый участки исходной кртинки
3. растянуть средний участок исходной кртинки и нарисовать на предже созданый TPngObject межде левым и правым участками.
4. Рисовать уже целый, готовый TPngObject на канве формы (OnPaint).
Таким образом пока не будет изменения размера формы не прейдеться заново делать кучу процедур что б получить изображение нужного размера, а будет оно сразу рисоваться с готового TPngObject.
Вот как создать новый прозрачный пнг чтоб потом все ето сделать. Или может используя 32 bit Bitmap или с помощью библиотеки Graphics32 ?
Andy BitOff (2010-09-20 10:47:00) [1]Или так...
procedure TForm1.FormPaint(Sender: TObject);
var
graphics, pngGraph : TGPGraphics;
pn, png: TGPBitmap;
begin
Canvas.TextOut(20, 50, 'Test : Test : Test : Test');
// на этом будем рисовать
graphics := TGPGraphics.Create(Canvas.Handle);
// здесь загрузим файл
pn := TGPBitmap.Create('Untitled-1.png');
// это чистый объект
png := TGPBitmap.Create(100, 100);
//если хотим на нем порисовать, то...
pngGraph := TGPGraphics.Create(png);
pngGraph. // и рисуем (надо создать браши, пэны и т.п.)
// можно вывести на него кусочек pn
pngGraph.DrawImage(pn, 10, 10, 10, 10, 30, 20, UnitPixel);
// выведем его на форму
graphics.DrawImage(png, 0, 0);
// и тоже выведем его
//graphics.DrawImage(pn, 0, 0);
png.Free;
pn.Free;
graphics.Free;
end;
Там уже как душе угодно.
Andy BitOff (2010-09-20 10:38:00) [2]Зачем такие сложности?
uses GDIPAPI, GDIPOBJ, GDIPUTIL
procedure TForm1.FormPaint(Sender: TObject);
var
graphics : TGPGraphics;
pn, png: TGPBitmap;
begin
Canvas.TextOut(20, 50, 'Test : Test : Test : Test');
// на этом будем рисовать
graphics := TGPGraphics.Create(Canvas.Handle);
// это чистый объект
png := TGPBitmap.Create(100, 100);
// выведем его на форму
graphics.DrawImage(png, 0, 0);
// здесь загрузим файл
pn := TGPBitmap.Create('Untitled-1.png');
// и тоже выведем его
graphics.DrawImage(pn, 0, 0);
png.Free;
pn.Free;
graphics.Free;
end;
MonoLife (2010-09-20 07:29:00) [3]
> Подскажите пожалуйста как создать чистый TPngObject. Под
> "чистым" имею в виду прозрачный а не заполненый каким то
> цветом, чтоб потом рисовать другие png на его канве.
Код antonn © навел на мысль:
а если типа такого для начала?
uses pngimage;
a, d: pByteArray;
....
//создаю один TPngObject чтоб загрузить картинку
PN:=TPngObject.Create;
//создаю чистый TPngObject
png := tpngobject.createblank(COLOR_RGBALPHA, 16, 150, 150);
PN.LoadFromFile('test.png');
arect:=Rect(0,0,pn.width, pn.height);
.......
for i:=0 to pn.height-1 do
begin
a:=PN.AlphaScanline[i];
for j:=0 to pn.width-1 do
begin
d:=png.AlphaScanline[i];
if a=nil then
d[j]:=255
else
d[j]:=a[j];
end;
end;
png.Canvas.CopyRect(arect, PN.Canvas, arect);
...
SIV5000 (2010-09-14 14:28:00) [4]
> Хм... Интерполяция? Бикубическая или что покруче? Можно
> взглянуть?)
Ну точно не знаю, я ведь только начинаю..... ну вот на Stack Overflow мне подогнали такую процедурку:
Все работает нормально.
procedure SmoothResize(apng:tpngobject; NuWidth,NuHeight:integer);
var
xscale, yscale : Single;
sfrom_y, sfrom_x : Single;
ifrom_y, ifrom_x : Integer;
to_y, to_x : Integer;
weight_x, weight_y : array[0..1] of Single;
weight : Single;
new_red, new_green : Integer;
new_blue, new_alpha : Integer;
new_colortype : Integer;
total_red, total_green : Single;
total_blue, total_alpha: Single;
IsAlpha : Boolean;
ix, iy : Integer;
bTmp : TPNGObject;
sli, slo : pRGBLine;
ali, alo: pbytearray;
begin
if not (apng.Header.ColorType in [COLOR_RGBALPHA, COLOR_RGB]) then
raise Exception.Create('Only COLOR_RGBALPHA and COLOR_RGB formats' +
' are supported');
IsAlpha := apng.Header.ColorType in [COLOR_RGBALPHA];
if IsAlpha then new_colortype := COLOR_RGBALPHA else
new_colortype := COLOR_RGB;
bTmp := Tpngobject.CreateBlank(new_colortype, 8, NuWidth, NuHeight);
xscale := bTmp.Width / (apng.Width-1);
yscale := bTmp.Height / (apng.Height-1);
for to_y := 0 to bTmp.Height-1 do begin
sfrom_y := to_y / yscale;
ifrom_y := Trunc(sfrom_y);
weight_y[1] := sfrom_y - ifrom_y;
weight_y[0] := 1 - weight_y[1];
for to_x := 0 to bTmp.Width-1 do begin
sfrom_x := to_x / xscale;
ifrom_x := Trunc(sfrom_x);
weight_x[1] := sfrom_x - ifrom_x;
weight_x[0] := 1 - weight_x[1];
total_red := 0.0;
total_green := 0.0;
total_blue := 0.0;
total_alpha := 0.0;
for ix := 0 to 1 do begin
for iy := 0 to 1 do begin
sli := apng.Scanline[ifrom_y + iy];
if IsAlpha then ali := apng.AlphaScanline[ifrom_y + iy];
new_red := sli[ifrom_x + ix].rgbtRed;
new_green := sli[ifrom_x + ix].rgbtGreen;
new_blue := sli[ifrom_x + ix].rgbtBlue;
if IsAlpha then new_alpha := ali[ifrom_x + ix];
weight := weight_x[ix] * weight_y[iy];
total_red := total_red + new_red * weight;
total_green := total_green + new_green * weight;
total_blue := total_blue + new_blue * weight;
if IsAlpha then total_alpha := total_alpha + new_alpha * weight;
end;
end;
slo := bTmp.ScanLine[to_y];
if IsAlpha then alo := bTmp.AlphaScanLine[to_y];
slo[to_x].rgbtRed := Round(total_red);
slo[to_x].rgbtGreen := Round(total_green);
slo[to_x].rgbtBlue := Round(total_blue);
if isAlpha then alo[to_x] := Round(total_alpha);
end;
end;
apng.Assign(bTmp);
bTmp.Free;
end;
> Что там у вас за "TBitmap32"?
С библиотеки Graphics32 ( http://graphics32.org/wiki/Main/HomePage)
_L_ (2010-09-13 23:46:00) [5]TPngObject хранит RGB отдельно от A...
Что там у вас за "TBitmap32"?
Кстати вы на VCL делаете? Тогда попробуйте такое:
// onformload
PN:=TPngObject.Create;
PN.LoadFromFile('test.png'); // 32bit
Image1.Width:=PN.Width;
Image1.Height:=PN.Height;
Image1.Picture.Assign(PN);
PN.Free;
> уже нашел как можно делать ресайз пнг
Хм... Интерполяция? Бикубическая или что покруче? Можно взглянуть?)
Andy BitOff (2010-09-11 23:26:00) [6]Возьми GDI+ !
SIV5000 (2010-09-11 22:08:00) [7]Пример с png_split я уже видел и разобрался что к чему. Ну задача в том что есть пнг картинки размером до 256х256 нужно их загружать и менять размер до нужного, ну допустим к 48х48. Я уже нашел как можно делать ресайз пнг. Но как я понял, библиотека Graphics32 более подходящая и быстрая, вот только нужно как то загрузить ПНГ в TBitmap32 без потери прозрачности.
Везде искал, но не нашел, а пример на сате Graphics32 создает белый фон.
Как же ето сделать???????
И вообще, подскажите, кто работает с Graphics32, рисование на канве TBitmap32 в действительности быстрее чем на обычном TBitmap? Просто пишу компонент, пока что все отрисовываеться на TBitmap, но рисовать нужно много так вот будет ли лучше рисовать на TBitmap32 ???
antonn (2010-09-11 14:45:00) [8]
> Подскажите хотя б как загрузить PNG в Bitmap32 (библиотека
> Graphics32) без потери прозрачности???
могу подсказать как загрузить PNG в обычный битмап - примерно как тут http://desksoft.ru/index.php?downloads=attachments&id=254
DVM (2010-09-11 12:38:00) [9]
> Битмап кстати изначально поддерживает альфаканал
скорее, битмап изначально поддерживает 32-битный цвет, т.е 4 байта на пиксель, а что будет в 4 байте, прозрачность или нет, решать тому кто использует. Т.е там необязательно прозрачность может быть потому наверное и нет согласия в вопросе отрисовки.
Rouse_ (2010-09-11 01:38:00) [10]Битмап кстати изначально поддерживает альфаканал, его просто почему-то отображать забывают повсеместно...
Вот... и еще, я не понял - зачем для данной задачи именно PNG?
Andy BitOff (2010-09-10 22:05:00) [11]Возьми GDI+
SIV5000 (2010-09-10 16:51:00) [12]Ну что никто с PNG ни разу не работал?!!!!
Подскажите хотя б как загрузить PNG в Bitmap32 (библиотека Graphics32) без потери прозрачности???
На сайте Graphics32 есть юнит GR32_PNG но PNG при загрузке все равно теряет прозрачность.