Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Мультимедиа в Delphi
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.05.2010, 20:08   #1
RidDozZ
 
Аватар для RidDozZ
 
Регистрация: 30.03.2010
Сообщений: 4
По умолчанию Ресайз PNG без потери прозрачности

Всем привет! Попал в такую ситуацию: есть 2 временных TPNGImage; один загружен из файла, второй - пустой, предназначен для вывода растянутого/ужатого первого.

При копировании первого во второй и его последующем ресайзе теряется альфа-канал.
Вот такого плана:

Код:
var
  Src,Dst:TPngImage;
  width,height:integer;
...
procedure Resize;
begin
  Dst.SetSize(width,height);
  Dst.StretchDraw(Dst.Canvas.ClipRect,Src);
end;
Как можно заново просчитать маску прозрачности (или как это делается), учитывая новые размеры?
Очень надеюсь на Вашу помощь. Спасибо!
RidDozZ вне форума Ответить с цитированием
Старый 07.05.2010, 04:39   #2
RidDozZ
 
Аватар для RidDozZ
 
Регистрация: 30.03.2010
Сообщений: 4
По умолчанию

Всем спасибо, сам разобрался)) Если кому понадобится - вот код:

Код:
var
  Src,Dst:TPngImage;
 
type
  PRGBAArray = ^TRGBAArray;
  TRGBAArray = array[0..MaxPixelCountA-1] of TRGBQuad;
...
procedure Resize;
var BTOut:TBitmap;
    BT:Tbitmap;   
    bt_tmp_rgb,bt_tmp_a:tbitmap;
    bt_tmp_rgb2,bt_tmp_a2:tbitmap;
    iii,ii:integer;
    fff:PRGBAArray;
    aaa:pByteArray;
begin
  BTOut:=TBitmap.Create;
  BTOut.PixelFormat:=pf32bit;
  
  BT:=TBitmap.Create;
  BT.PixelFormat:=pf32bit;
 
  bt_tmp_rgb:=TBitmap.Create;
  bt_tmp_a:=TBitmap.Create;
  bt_tmp_rgb.PixelFormat:=pf32bit;
  bt_tmp_a.PixelFormat:=pf32bit;
 
  BT.Assign(Src);
  for ii:=0 to BT.Height-1 do begin
    fff:=BT.ScanLine[ii];
    aaa:=Src.AlphaScanline[ii];
    for iii:=0 to BT.Width-1 do begin
      fff[iii].rgbReserved:=aaa[iii];
    end;
  end;
  BTOut.SetSize(Dst.Width,Dst.Height);
  bt_tmp_rgb.SetSize(BT.Width,BT.Height);
  bt_tmp_a.SetSize(BT.Width,BT.Height);
 
  //Разделяем битмап-подложку на "видимый" битмап RGB и альфаканал
  GetLayerBitmap(bt,bt_tmp_rgb,bt_tmp_a);
  BT.Free;
  bt_tmp_rgb2:=TBitmap.Create;
  bt_tmp_rgb2.PixelFormat:=pf32bit;
  bt_tmp_rgb2.SetSize(BTOut.Width,BTOut.Height);
  bt_tmp_rgb2.Canvas.StretchDraw(bt_tmp_rgb2.Canvas.ClipRect,bt_tmp_rgb);
  bt_tmp_rgb.Free;
  bt_tmp_a2:=TBitmap.Create;
  bt_tmp_a2.PixelFormat:=pf32bit;
  bt_tmp_a2.SetSize(BTOut.Width,BTOut.Height);
  bt_tmp_a2.Canvas.StretchDraw(bt_tmp_a2.Canvas.ClipRect,bt_tmp_a);
  bt_tmp_a.Free;
 
  //собираем временные битмапы в один 32-битный, который потом будет отображен
  Build32(bt_tmp_rgb2,bt_tmp_a2,BTOut);
  bt_tmp_rgb2.Free;
  bt_tmp_a2.Free;
  Dst.Assign(BTOut);
  Dst.CreateAlpha;
 
  for ii:=0 to BTOut.Height-1 do begin
    fff:=BTOut.ScanLine[ii];
    aaa:=Layer.StretchPNG.AlphaScanline[ii];
    for iii:=0 to BTOut.Width-1 do begin
      aaa[iii]:=fff[iii].rgbReserved;
    end;
  end;
 
  BTOut.Free;
end;
 
procedure GetLayerBitmap(_B_res:TBitmap;  _Brgb,_Bmask:Tbitmap);
var x, y: Integer; RowOut,RowIn,RowOutM: PRGBAArray;
begin
  for y:=0 to _B_res.Height-1 do begin
    RowOut:= _Brgb.ScanLine[y];
    RowOutM:= _Bmask.ScanLine[y];
    RowIn:= _B_res.ScanLine[y];
    for x:=0 to _B_res.Width-1 do begin
 
     RowOutM[x].rgbReserved:=255;
     RowOutM[x].rgbBlue:=RowIn[x].rgbReserved;
     RowOutM[x].rgbGreen:=RowIn[x].rgbReserved;
     RowOutM[x].rgbRed:=RowIn[x].rgbReserved;
 
     RowOut[x].rgbReserved:=255;
     RowOut[x].rgbBlue:=RowIn[x].rgbBlue;
     RowOut[x].rgbGreen:=RowIn[x].rgbGreen;
     RowOut[x].rgbRed:=RowIn[x].rgbRed;
     end;
  end;
end;
 
procedure Build32(_B_in,_B_inM:TBitmap; _Bout:Tbitmap);
var x, y: Integer; RowOut: PRGBAArray; RowIn,RowM:PRGBAArray;
begin
  for y:=0 to _B_in.Height-1 do begin
     RowOut:= _Bout.ScanLine[y];
     RowIn:= _B_in.ScanLine[y];
     RowM:= _B_inM.ScanLine[y];
    for x:=0 to _B_in.Width-1 do begin
          RowOut[x].rgbBlue:=RowIn[x].rgbBlue;
          RowOut[x].rgbGreen:=RowIn[x].rgbGreen;
          RowOut[x].rgbRed:=RowIn[x].rgbRed;
          RowOut[x].rgbReserved:=RowM[x].rgbRed;
    end;
  end;
end;
Код сырой, конечно, но для начала и такого достаточно.
RidDozZ вне форума Ответить с цитированием
Старый 01.08.2012, 13:40   #3
X11
Пользователь
 
Регистрация: 20.01.2010
Сообщений: 54
По умолчанию

а что такое Layer.StretchPNG и откуда у него ноги растут?
X11 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Если остановился поток (TThread). Как перезапустить без потери памяти Zuzlan Общие вопросы Delphi 9 01.02.2011 13:57
Добавление FieldDefs в ClientDataSet без потери записей shock-in Общие вопросы Delphi 1 04.12.2009 01:18
Спрятать файл внутри другого файла без потери работоспособности обоих V@Noff Общие вопросы Delphi 9 03.11.2009 16:18
Убрать точки без потери данных king13 Microsoft Office Excel 4 07.10.2009 13:54
Копирование таблицы без потери форматирования k1r1ch Microsoft Office Excel 3 09.07.2009 11:00