На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> Наложить тень на картинку , Тень Луны в GDI+
    Необходимо, при помощи GDI+, вывести на десктоп картинку Луны и наложить на нее тень. С выводом картинки проблем нет. Код ниже, за исключением нескольких строк для таскания мышкой и popup menu.

    Не получается вывести тень. Алгоритм рисования тени позаимствован на просторах Инета из старой проги. Вкратце он следующий:
    - В зависимости от фазы Луны, левая или правая половинка диска темная (рисуем сектор эллипса).
    - Уточняем фазу и рисуем посередине эллипс. Если эллипс темный - тень увеличивется, белый - тень становится меньше.

    Используя TGPGraphics.FillEllipse (FillPie) и полупрозрачную черную кисть тень отлично рисуется. Но только если она в половину или более диска Луны. Попытка использовать полупрозрачную белую кисть поверх черной привела к закономерному извращению. Как назначить белый цвет прозрачным не нашел. Я так понимаю, что при наличии альфа канала эта возможность не нужна.

    Можно порисовать в обычном TBitmap по описанному алгоритму. Назначить нужный цвет прозрачным. И даже, видал на форумах, сделать полупрозрачным. Но как потом натянуть его на картинку средствами GDI+ сообразить не могу.

    Что посоветуете?

    ExpandedWrap disabled
      procedure TMoonForm.FormCreate(Sender: TObject);
      Var
        screendc  : HDC;
        img       : TGPBitmap;//GDI+
        hbmp      : HBITMAP; //Прозрачная картинка
        backdc    : HDC; //Контекст для прозрачной картинки
        pt1, pt2  : TPoint;
        sz        : TSize;
        BF          : TBlendFunction;//Прозрачность Луны
        AlphaShadow : Byte;
      begin
        //Если есть ini, то читаем из него
        if FileExists(ExtractFilePath(Application.ExeName)+'MoonCalendar.ini') then
        begin
          MoonForm.Left:=Inif.ReadInteger('FormPlace','Left');
          MoonForm.Top :=Inif.ReadInteger('FormPlace','Top');
          BF.SourceConstantAlpha:=Inif.ReadInteger('View','AlphaMoon');
          AlphaShadow:=Inif.ReadInteger('View','AlphaShadow');
        end;
        //Если прозрачность 0 или больше чем байт, то ставим макс.значение 255
        if (BF.SourceConstantAlpha=0) OR (BF.SourceConstantAlpha>255) then
          BF.SourceConstantAlpha:=255;
        //Если прозрачность 0 или больше чем байт, то ставим макс.значение 255
        if (AlphaShadow=0) OR (AlphaShadow>255) then
          AlphaShadow:=255;
        Application.HintHidePause:=10000;//Время показа подсказки 10 сек
        // Убираем рамку окна. Иначе ничего не выйдет.
        Self.BorderStyle := bsNone;
        // Делаем окно многослойным
        if SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or
        WS_EX_LAYERED) = 0 then ShowMessage(SysErrorMessage(GetLastError));
        // Загружаем 32-битный PNG с альфа каналом и получаем его HBITMAP
        img := TGPBitmap.Create('moon3.png',True);
       
      //Можно порисовать используя TGPGraphics
      //  GPgrahpMoon:=TGPGraphics.Create(img);
       
        //HBITMAP
        with img do begin
          GetHBITMAP(0,hbmp);
          Width  := GetWidth;
          Height := GetHeight;
          Free;
        end;
        // Получаем контекст экрана
        screendc := GetDC(0);
        // Создаем контекст, совместимый с экраном
        backdc := CreateCompatibleDC(screendc);
        // Загружаем в него картинку
        SelectObject(backdc, hbmp);
        // Вызываем UpdateLayeredWindow
        pt1 := Point(Left, Top);
        pt2 := Point(0,0);
        sz.cx := Width;
        sz.cy := Height;
        with bf do begin
          BlendOp := AC_SRC_OVER;
          BlendFlags := 0;
      //    SourceConstantAlpha := $FF; // Можно ставить общую прозрачность
          AlphaFormat := AC_SRC_ALPHA;
        end;
        UpdateLayeredWindow(Handle,screendc,@pt1,@sz,backdc,@pt2,0,@bf,ULW_ALPHA);
        // Освобождаем контекст экрана
        ReleaseDC(0,screendc);
      end;
    Сообщение отредактировано: Sandy -
      Пока решил поступить следующим образом:
      1. Рисую на TGPBitmap с альфа каналом непрозрачными кистями.
      2. Обхожу каждый пиксел и убиваю белый цвет, а черный делаю полупрозрачным.
      3. Натягиваю bmp на картинку Луны.

      ExpandedWrap disabled
          bmpShadow:=TGPBitmap.Create(128,128,PixelFormat32bppARGB);
          gp:=TGPGraphics.Create(bmpShadow);
          WhiteColor:=MakeColor(255,255,255,255);
          BlackColor:=MakeColor(255,0,0,0);
          BlackBrush:=TGPSolidBrush.Create(BlackColor);
          WhiteBrush:=TGPSolidBrush.Create(WhiteColor);
          //Рисуем
          gp.FillEllipse и т.д.
          //Обесцвечиваем белые пиксели,
          //а черные делаем полупрозрачными
          ClearColor:=MakeColor(0,0,0,0);
          AlphaBlackColor:=MakeColor(96,0,0,0);
          For Y:=0 to bmpShadow.GetHeight-1 do
            For X:=0 to bmpShadow.GetWidth-1 do
            begin
              bmpShadow.GetPixel(X,Y,bmpColor);
              if bmpColor=WhiteColor then
                bmpShadow.SetPixel(X,Y,ClearColor)
              else
                if bmpColor=BlackColor then
                  bmpShadow.SetPixel(X,Y,AlphaBlackColor);
            end;
          //Загружаем 32-битный PNG с альфа каналом (картинка Луны)
          pngMoon:=TGPBitmap.Create('moon3.png',True);
          graphShadow:=TGPGraphics.Create(pngMoon);
          graphShadow.DrawImage(bmpShadow,0,0,128,128);//Натягиваем тень на картинку

      Но этот метод мне кажется не очень оптимальным, все же не scanline. А еще захотелось размыть границу терминатора, тоже должно замедлять.

      ExpandedWrap disabled
        //Код взят с http://www.kansoftware.ru/?tid=363 Но вообще, попадается повсеместно.
        //Размытие изображения. Прозрачности каждой точки присваивается
        // среднее значение цветов соседних точек.
        procedure Blur(var TransGPBitmap:TGPBitmap);
        const
          width = 128;
          height = 128;
          d = 2;
        var
          x, y: integer;
          i, j: integer;
          c: integer;
          Pix: array [0..width-1, 0..height-1] of byte;
          rColor:TGPColor;
        begin
          randomize;
          with TransGPBitmap do
          begin
            for y := 0 to height - 1 do
              for x := 0 to width - 1 do
              begin
                GetPixel(x,y,rColor);
                //Посмотреть почему ошибка на rColor.GetAlpha;
                Pix[x,y] := BYTE(rColor shr AlphaShift);
              end;
            for y := d to height - d - 1 do
              for x := d to width - d - 1 do
              begin
                c := 0;
                for i := -d to d do
                  for j := -d to d do
                    c := c + Pix[x+i,y+j];
                c := round(c / sqr(2 * d + 1));
                SetPixel(x,y,MakeColor(c,BYTE(rColor shr RedShift),BYTE(rColor shr GreenShift),BYTE(rColor shr BlueShift)));
              end;
          end;
        end;

      В общем вопрос остался прежним. Может стоит изучить TGPImageAttributes.SetRemapTable(2,@ColorMap)? Сходу применить не получилось, есть работающий пример?
        Получилось вроде того
        http://my-files.ru/dczr3p
        Не знаю, что за файлообменник, но вроде ничего не просит за скачивание.
        P.S. Прога, после закрытия создает ini. Так что не удивляйтесь появлению левого файла.
          Э, а где фулл сорс коде? зачем мне этот эгзе ?
          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
          0 пользователей:


          Рейтинг@Mail.ru
          [ Script execution time: 0,0328 ]   [ 17 queries used ]   [ Generated: 29.03.24, 02:11 GMT ]