Прозрачность PNG в проектах Lazarus ...

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: Прозрачность PNG в проектах Lazarus ...

Сообщение Logo » 02.08.2009 00:25:33

QT в крапинку :(
Logo
постоялец
 
Сообщения: 464
Зарегистрирован: 20.08.2008 01:00:47

Re: Прозрачность PNG в проектах Lazarus ...

Сообщение carrots » 02.08.2009 02:28:13

Ага, маска ему не понравилась, а с хандела в GTK вытянуть альфу не возможно

Вот более чистый вариант

Заменяем только процедуру TRasterImage.Draw в rasterimage.inc

Код: Выделить всё
procedure TRasterImage.Draw(DestCanvas: TCanvas; const DestRect: TRect);
var
  UseMaskHandle: HBitmap;
  SrcDC: hDC;
  DestDC: hDC;
  DstBmp:TBitmap;
  RShift, GShift, BShift, AShift, DstRShift, DstGShift, DstBShift:Integer;
  RWidth, RHeight:integer;
  ix, iy, iyStartByte, dstiyStartByte:integer;
  srcdata, dstdata: PByteArray;
  tmpdc:HDC;
  bmp, old: HBitmap;
  msk: HBitmap;
  FinishX:Integer;
  FinishY:Integer;
  DP, SP:integer;
  SrcPR, DstPR:byte;
  SrcWidthPR,SrcHeightPR:single;
begin
  if (Width=0) or (Height=0)
  then Exit;

  BitmapHandleNeeded;
  if not BitmapHandleAllocated then Exit;

  if Masked then
    UseMaskHandle:=MaskHandle
  else
    UseMaskHandle:=0;

  DestCanvas.Changing;
  DestDC := DestCanvas.GetUpdatedHandle([csHandleValid]);


  if ((WidgetSet.LCLPlatform = lpGtk) or (WidgetSet.LCLPlatform = lpGtk2)) and
    (PixelFormat = pf32bit) and (RawImage.Description.BitsPerPixel = 32) and
     (RawImage.Description.Format = ricfRGBA)  then
  begin

     RWidth:= DestRect.Right-DestRect.Left;
     RHeight:= DestRect.Bottom-DestRect.Top;

     DstBmp := TBitmap.Create;
     DstBmp.PixelFormat:=pf32bit;
     DstBmp.SetSize(RWidth,RHeight);
     DstBmp.Canvas.CopyRect(rect(0,0,DstBmp.Width,DstBmp.Height),DestCanvas,DestRect);
     try
      srcdata:=PByteArray(RawImage.Data);
      dstdata:=PByteArray(DstBmp.RawImage.Data);

      RShift:=RawImage.Description.RedShift div 8;
      GShift:=RawImage.Description.GreenShift div 8;
      BShift:=RawImage.Description.BlueShift div 8;
      AShift:=RawImage.Description.AlphaShift div 8;

      DstRShift:=DstBmp.RawImage.Description.RedShift div 8;
      DstGShift:=DstBmp.RawImage.Description.GreenShift div 8;
      DstBShift:=DstBmp.RawImage.Description.BlueShift div 8;

      FinishY:=min(rHeight,DstBmp.RawImage.Description.Height);
      FinishX:=min(rWidth,DstBmp.RawImage.Description.Width);
      if (Height = rHeight)and(Width = rWidth) then
      begin
        for iy := 0 to FinishY-1 do
        begin
          iyStartByte := iy*RawImage.Description.Width;
          dstiyStartByte := iy*dstBmp.RawImage.Description.Width;
          for ix := 0 to FinishX-1 do
          begin
            DP :=((ix+dstiyStartByte)*4);
            SP :=((ix+iyStartByte)*4);
            SrcPR:=srcdata^[SP+AShift];
            DstPR:=255-SrcPR;
            dstdata^[DP+DstRShift]:=((srcdata^[SP+RShift]*SrcPR)+(dstdata^[DP+DstRShift]*DstPR)) div 255;
            dstdata^[DP+DstGShift]:=((srcdata^[SP+GShift]*SrcPR)+(dstdata^[DP+DstGShift]*DstPR)) div 255;
            dstdata^[DP+DstBShift]:=((srcdata^[SP+BShift]*SrcPR)+(dstdata^[DP+DstBShift]*DstPR)) div 255;
          end;
        end;
      end else
      begin
        SrcWidthPR:=Width/RWidth;
        SrcHeightPR:=Height/RHeight;
        for iy := 0 to FinishY-1 do
        begin
          iyStartByte := trunc(iy*SrcHeightPR)*RawImage.Description.Width;
          dstiyStartByte := iy*dstBmp.RawImage.Description.Width;
          for ix := 0 to FinishX-1 do
          begin
            DP :=((ix+dstiyStartByte)*4);
            SP :=((trunc(ix*SrcWidthPR)+iyStartByte)*4);
            SrcPR:=srcdata^[SP+AShift];
            DstPR:=255-SrcPR;
            dstdata^[DP+RShift]:=((srcdata^[SP+RShift]*SrcPR)+(dstdata^[DP+RShift]*DstPR))div 255;
            dstdata^[DP+GShift]:=((srcdata^[SP+GShift]*SrcPR)+(dstdata^[DP+GShift]*DstPR))div 255;
            dstdata^[DP+BShift]:=((srcdata^[SP+BShift]*SrcPR)+(dstdata^[DP+BShift]*DstPR))div 255;
          end;
        end;
      end;

      WidgetSet.RawImage_CreateBitmaps(dstBmp.RawImage, bmp, msk, false);
      tmpDC := CreateCompatibleDC(DestDC);
      old := SelectObject(tmpDC, bmp);

      StretchMaskBlt(DestDC, DestRect.Left, DestRect.Top, DstBmp.RawImage.Description.Width, DstBmp.RawImage.Description.Height, TmpDC,  0, 0, DstBmp.RawImage.Description.Width, DstBmp.RawImage.Description.Height,
      0, 0,0,DestCanvas.CopyMode);


    finally
      DeleteObject(SelectObject(tmpDC, old));
      DeleteObject(msk);
      DeleteDC(tmpDC);
      DstBmp.Free;
    end;

  end else
  begin
    SrcDC := Canvas.GetUpdatedHandle([csHandleValid]);
    StretchMaskBlt(DestDC,
            DestRect.Left,DestRect.Top,
            DestRect.Right-DestRect.Left,DestRect.Bottom-DestRect.Top,
            SrcDC,0,0,Width,Height, UseMaskHandle,0,0,DestCanvas.CopyMode);
  end;

  DestCanvas.Changed;
end;

Последний раз редактировалось carrots 02.08.2009 05:35:43, всего редактировалось 1 раз.
Аватара пользователя
carrots
постоялец
 
Сообщения: 138
Зарегистрирован: 28.03.2008 02:13:02

Re: Прозрачность PNG в проектах Lazarus ...

Сообщение Logo » 02.08.2009 03:43:46

Работает.
Хотя это и не поддерживает идеологию разработчиков, но на данный момент нормальное решение, всеравно GTK скоро в корне переработают и нужно будет искать новые решения.
Logo
постоялец
 
Сообщения: 464
Зарегистрирован: 20.08.2008 01:00:47

Re: Прозрачность PNG в проектах Lazarus ...

Сообщение Andreich » 02.08.2009 23:17:43

carrots писал(а):... под suse, mandriva, debian, под gnome и KDE, везде работает, так что причина наверное в старом lazarus и FPC

Возможно действительно это из-за того, что я использую 0.9.26,.. еще немного повожусь и если не получится, то попробую обновиться до версии 0.9.27 из SVN.
Andreich
постоялец
 
Сообщения: 268
Зарегистрирован: 17.04.2008 12:33:43

Re: Прозрачность PNG в проектах Lazarus ...

Сообщение Logo » 03.08.2009 04:09:43

Andreich писал(а):Возможно действительно это из-за того, что я использую 0.9.26,..

Проверил, действительно в 0.9.26 рисует мусор на фоне.
Logo
постоялец
 
Сообщения: 464
Зарегистрирован: 20.08.2008 01:00:47

Re: Прозрачность PNG в проектах Lazarus ...

Сообщение carrots » 07.08.2009 23:36:12

Logo писал(а):Работает.
Хотя это и не поддерживает идеологию разработчиков, но на данный момент нормальное решение

Как понять не поддерживает идеологию разработчиков?
Не в виджетсете написано?
Для того чтоб сделать по принципу разработчиков нужно будет добавить новый параметр в существующую процедуру или создать новую процедуру переноса изображений, ради чего придется вносить изменения во все виджетсеты, это не удобной и не нужно.
GTK 3 будет отдельной историей которая будет поддерживаться помимо 1 и 2.
В lazarus 9.26 возвращаться нет смысла, так что работает под ним или нет не имеет особого значения.
Аватара пользователя
carrots
постоялец
 
Сообщения: 138
Зарегистрирован: 28.03.2008 02:13:02

Re: Прозрачность PNG в проектах Lazarus ...

Сообщение Logo » 08.08.2009 15:13:39

carrots писал(а):Не в виджетсете написано?

Ага, - не кошерно. Хотя я лично пользуюсь твоей заплаткой, за что ОГРОМНОЕ СПАСИБО!!!
carrots писал(а):В lazarus 9.26 возвращаться нет смысла, так что работает под ним или нет не имеет особого значения.

Согласен, слишком уж много улучшений в 0.9.27, чтобы возвращаться к прошлому. ВПЕРЕД и только ВПЕРЕД!!!
Logo
постоялец
 
Сообщения: 464
Зарегистрирован: 20.08.2008 01:00:47

Re: Прозрачность PNG в проектах Lazarus ...

Сообщение carrots » 26.09.2009 14:39:08

Уже 0.2.29 делают, а прозрачности как не было так и нет.
До сих пор приходится патчить. :(
Интересно они вообще собираются эту проблему решать?
Аватара пользователя
carrots
постоялец
 
Сообщения: 138
Зарегистрирован: 28.03.2008 02:13:02

Re: Прозрачность PNG в проектах Lazarus ...

Сообщение Павел Ишенин » 26.09.2009 15:01:57

Интересно они вообще собираются эту проблему решать?


Проблем как всегда много. За всеми не угонишься. Прозрачностью будет заниматься Marc Weustink после возвращения из отпуска. Эту тему я ему показывал.
Павел Ишенин
постоялец
 
Сообщения: 475
Зарегистрирован: 24.03.2007 10:16:52

Re: Прозрачность PNG в проектах Lazarus ...

Сообщение Logo » 26.09.2009 15:48:54

carrots писал(а):Уже 0.2.29 делают, а прозрачности как не было так и нет.
До сих пор приходится патчить. :(
Интересно они вообще собираются эту проблему решать?

Не нервничай, чем патч не нравится? Работает нормально, а по-правилам потом сделают. Тем более, что при обновлении с SVN пропатченый модуль остается не тронутым - все Ок!
Logo
постоялец
 
Сообщения: 464
Зарегистрирован: 20.08.2008 01:00:47

Re: Прозрачность PNG в проектах Lazarus ...

Сообщение AbakAngelSoft » 24.12.2010 11:49:55

carrots писал(а):Ага, маска ему не понравилась, а с хандела в GTK вытянуть альфу не возможно

Вот более чистый вариант

Заменяем только процедуру TRasterImage.Draw в rasterimage.inc

Код: Выделить всё
procedure TRasterImage.Draw(DestCanvas: TCanvas; const DestRect: TRect);
var
  UseMaskHandle: HBitmap;
  SrcDC: hDC;
  DestDC: hDC;
  DstBmp:TBitmap;
  RShift, GShift, BShift, AShift, DstRShift, DstGShift, DstBShift:Integer;
  RWidth, RHeight:integer;
  ix, iy, iyStartByte, dstiyStartByte:integer;
  srcdata, dstdata: PByteArray;
  tmpdc:HDC;
  bmp, old: HBitmap;
  msk: HBitmap;
  FinishX:Integer;
  FinishY:Integer;
  DP, SP:integer;
  SrcPR, DstPR:byte;
  SrcWidthPR,SrcHeightPR:single;
begin
  if (Width=0) or (Height=0)
  then Exit;

  BitmapHandleNeeded;
  if not BitmapHandleAllocated then Exit;

  if Masked then
    UseMaskHandle:=MaskHandle
  else
    UseMaskHandle:=0;

  DestCanvas.Changing;
  DestDC := DestCanvas.GetUpdatedHandle([csHandleValid]);


  if ((WidgetSet.LCLPlatform = lpGtk) or (WidgetSet.LCLPlatform = lpGtk2)) and
    (PixelFormat = pf32bit) and (RawImage.Description.BitsPerPixel = 32) and
     (RawImage.Description.Format = ricfRGBA)  then
  begin

     RWidth:= DestRect.Right-DestRect.Left;
     RHeight:= DestRect.Bottom-DestRect.Top;

     DstBmp := TBitmap.Create;
     DstBmp.PixelFormat:=pf32bit;
     DstBmp.SetSize(RWidth,RHeight);
     DstBmp.Canvas.CopyRect(rect(0,0,DstBmp.Width,DstBmp.Height),DestCanvas,DestRect);
     try
      srcdata:=PByteArray(RawImage.Data);
      dstdata:=PByteArray(DstBmp.RawImage.Data);

      RShift:=RawImage.Description.RedShift div 8;
      GShift:=RawImage.Description.GreenShift div 8;
      BShift:=RawImage.Description.BlueShift div 8;
      AShift:=RawImage.Description.AlphaShift div 8;

      DstRShift:=DstBmp.RawImage.Description.RedShift div 8;
      DstGShift:=DstBmp.RawImage.Description.GreenShift div 8;
      DstBShift:=DstBmp.RawImage.Description.BlueShift div 8;

      FinishY:=min(rHeight,DstBmp.RawImage.Description.Height);
      FinishX:=min(rWidth,DstBmp.RawImage.Description.Width);
      if (Height = rHeight)and(Width = rWidth) then
      begin
        for iy := 0 to FinishY-1 do
        begin
          iyStartByte := iy*RawImage.Description.Width;
          dstiyStartByte := iy*dstBmp.RawImage.Description.Width;
          for ix := 0 to FinishX-1 do
          begin
            DP :=((ix+dstiyStartByte)*4);
            SP :=((ix+iyStartByte)*4);
            SrcPR:=srcdata^[SP+AShift];
            DstPR:=255-SrcPR;
            dstdata^[DP+DstRShift]:=((srcdata^[SP+RShift]*SrcPR)+(dstdata^[DP+DstRShift]*DstPR)) div 255;
            dstdata^[DP+DstGShift]:=((srcdata^[SP+GShift]*SrcPR)+(dstdata^[DP+DstGShift]*DstPR)) div 255;
            dstdata^[DP+DstBShift]:=((srcdata^[SP+BShift]*SrcPR)+(dstdata^[DP+DstBShift]*DstPR)) div 255;
          end;
        end;
      end else
      begin
        SrcWidthPR:=Width/RWidth;
        SrcHeightPR:=Height/RHeight;
        for iy := 0 to FinishY-1 do
        begin
          iyStartByte := trunc(iy*SrcHeightPR)*RawImage.Description.Width;
          dstiyStartByte := iy*dstBmp.RawImage.Description.Width;
          for ix := 0 to FinishX-1 do
          begin
            DP :=((ix+dstiyStartByte)*4);
            SP :=((trunc(ix*SrcWidthPR)+iyStartByte)*4);
            SrcPR:=srcdata^[SP+AShift];
            DstPR:=255-SrcPR;
            dstdata^[DP+RShift]:=((srcdata^[SP+RShift]*SrcPR)+(dstdata^[DP+RShift]*DstPR))div 255;
            dstdata^[DP+GShift]:=((srcdata^[SP+GShift]*SrcPR)+(dstdata^[DP+GShift]*DstPR))div 255;
            dstdata^[DP+BShift]:=((srcdata^[SP+BShift]*SrcPR)+(dstdata^[DP+BShift]*DstPR))div 255;
          end;
        end;
      end;

      WidgetSet.RawImage_CreateBitmaps(dstBmp.RawImage, bmp, msk, false);
      tmpDC := CreateCompatibleDC(DestDC);
      old := SelectObject(tmpDC, bmp);

      StretchMaskBlt(DestDC, DestRect.Left, DestRect.Top, DstBmp.RawImage.Description.Width, DstBmp.RawImage.Description.Height, TmpDC,  0, 0, DstBmp.RawImage.Description.Width, DstBmp.RawImage.Description.Height,
      0, 0,0,DestCanvas.CopyMode);


    finally
      DeleteObject(SelectObject(tmpDC, old));
      DeleteObject(msk);
      DeleteDC(tmpDC);
      DstBmp.Free;
    end;

  end else
  begin
    SrcDC := Canvas.GetUpdatedHandle([csHandleValid]);
    StretchMaskBlt(DestDC,
            DestRect.Left,DestRect.Top,
            DestRect.Right-DestRect.Left,DestRect.Bottom-DestRect.Top,
            SrcDC,0,0,Width,Height, UseMaskHandle,0,0,DestCanvas.CopyMode);
  end;

  DestCanvas.Changed;
end;



Правильно ли я понимаю:
Необходимо этот код вставить в файл /usr/lib/lazarus/0.9.28.2/lcl/include/rasterimage.inc вместо имеющейся там TRasterImage.Draw и собрать lazarus?
После этих действий png изображение с альфа каналом загруженное в TImage или TImageList должно отображаться без "лесенки" по краям, как и в gimp-е?
Если да, то почему после указанных действий в "Ubuntu 10.04 x64" + "Lazarus 0.9.28.2-8ubuntu1 бета" изображения остаются "лесенкой"?
Аватара пользователя
AbakAngelSoft
постоялец
 
Сообщения: 273
Зарегистрирован: 06.08.2008 19:28:26
Откуда: Краснодар

Re: Прозрачность PNG в проектах Lazarus ...

Сообщение AbakAngelSoft » 27.12.2010 12:29:03

Неужели никто не сталкивался с указанными проблемами?
... Руки у меня что ли не от туда растут :( ...
Аватара пользователя
AbakAngelSoft
постоялец
 
Сообщения: 273
Зарегистрирован: 06.08.2008 19:28:26
Откуда: Краснодар

Пред.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 30

Рейтинг@Mail.ru