На главную
ПРАВИЛА FAQ Помощь Участники Календарь Избранное DigiMania RSS
msm.ru
Модераторы: Rouse_, jack128, Krid
  
    > Наложение полупрозрачного текста на Jpeg, регулируется прозрачность, цвет, размер шрифта, align, смещение текста.
      Наложение полупрозрачного текста на Jpeg
      Несколько раз уж требовалась внятная функция, для наложения полу-прозрачного текста на jpg. Очень досадно, что в DRKB информации по теме нет. На сей раз перелопатив несколько исходников(в инэте бродит с внесёнными порожняками), сварганил работающий вариант. Мне хватает, надеюсь и другим поможет.
      ExpandedWrap disabled
        {
        ================================================================================
                         Наложение полу-прозрачного текста на Jpg
        --------------------------------------------------------------------------------
          требования: Uses jpeg;
        размещать выше процедуры, из которой будет вызываться TextToBitmap.
          вызов:
        TextToBitmap('Текст', jpg, 70, rgb(255,255,255), 30, alLeft,alTop, 0, 0);
                              |     |   |                |   |       |     |  |
                              1     2   3                4   5.1     5.2  6.1 6.2
        1: Изображение, на которое будет нанесён текст
        2: Размер шрифта
        3: Цвет шрифта
        4: Прозрачность текста (0 - невидимый, 255 - непрозрачный)
        5: Выравнивание по 1.горизонтали 2.вертикали
           примечание: alClient - центровка;
           +работающие значения: alRight, alBottom - любые другие = alNone.
        6: Смешение текста 1.вправо 2.вниз
         
        Пример вызова:
        Uses jpeg;
        .....
        var jpg: TJPEGImage;
        begin
          jpg:=TJPEGImage.Create;
          jpg.LoadFromFile('c:\windows\web\wallpaper\Тюльпаны.jpg');
          TextToBitmap('Текст', jpg, 90, rgb(255,255,255), 30, alLeft,alTop, 50, 50);
          Form1.canvas.StretchDraw(Rect(0,0,jpg.Width,jpg.Height),jpg);
          jpg.Free;
         
        Васильев Владимир Викторович aka C800H. г.Евпатория. uin(icq): 300011169
        }
         
        //создать канал прозрачности (типа того)
        procedure BuildTextBmp(var b_rgb,b_mask,b_out:TBitmap);
        const MaxPixelCountA = MaxInt div SizeOf(TRGBQuad);
        type PRGBAArray=^TRGBAArray;
             TRGBAArray=array[0..MaxPixelCountA-1] of TRGBQuad;
        var x,y: Integer;
            rrgb,rmask,RowOut: PRGBAArray;
        begin
          for y:=0 to b_rgb.Height-1 do
          begin
            RowOut:=b_out.ScanLine[y];
            rrgb:=b_rgb.ScanLine[y];
            rmask:=b_mask.ScanLine[y];
            for x:=0 to b_rgb.Width-1 do
            begin
              RowOut[x].rgbReserved:=rmask[x].rgbRed;
              RowOut[x].rgbRed:=rrgb[x].rgbRed;
              RowOut[x].rgbGreen:=rrgb[x].rgbGreen;
              RowOut[x].rgbBlue:=rrgb[x].rgbBlue;
            end;
          end;
        end;
        //BmpText - входящий битмап с прозрачностью(BmpText) - накладывается на CanvasOut.
        procedure BlendBitmap_GDI(CanvasOut:TCanvas; BmpText:TBitmap; TextPosX,TextPosY:integer);
        const MaxPixelCountA=(MaxInt div SizeOf(TRGBQuad))-1;
        type TRGBAArray=array[0..MaxPixelCountA] of TRGBQuad;
             PRGBAArray=^TRGBAArray;
        var TextW,TextH,DstW,DstH: Integer;
           BmpBuff:TBitmap;
           x,y,lti:Integer;
           PSource,PDest:PRGBAArray;
           trans:double;
        begin
          if (TextPosX<0) or (TextPosY<0) or (BmpText.PixelFormat<>pf32bit) then Exit;
         
          TextW:=BmpText.Width;
          TextH:=BmpText.Height;
          if (TextW<1) or (TextH<1) then exit; //нет текста - выход
         
          DstW:=CanvasOut.ClipRect.Right-CanvasOut.ClipRect.Left;
          DstH:=CanvasOut.ClipRect.Bottom-CanvasOut.ClipRect.Top;
          if (DstW<TextW+TextPosX) or (DstH<TextH+TextPosY) then Exit;//текст "не влазит" - выход
         
          BmpBuff:=TBitmap.Create;
          BmpBuff.Width:=TextW;
          BmpBuff.Height:=TextH;
          BmpBuff.PixelFormat:=pf32bit;
         
          try
            BmpBuff.Canvas.CopyRect(Rect(0,0,BmpBuff.Width,BmpBuff.Height), CanvasOut, Rect(TextPosX,TextPosY,TextPosX+TextW,TextPosY+TextH));
            for y:=0 to TextH-1 do
            begin
              PSource:=BmpText.ScanLine[y];
              PDest:=BmpBuff.ScanLine[y];
              for x:=0 to TextW-1 do
              begin
                //прозрачность
                if PSource[x].rgbReserved>0 then
                  trans:=0.004*PSource[x].rgbReserved else trans:=0;
         
                lti:=round(PDest[x].rgbRed+(PSource[x].rgbRed-PDest[x].rgbRed)*trans);
                if lti>255 then lti:=255 else if lti<0 then lti:=0;
                PDest[x].rgbRed:=lti;
         
                lti:=round(PDest[x].rgbGreen+(PSource[x].rgbGreen-PDest[x].rgbGreen)*trans);
                if lti>255 then lti:=255 else if lti<0 then lti:=0;
                PDest[x].rgbGreen:=lti;
         
                lti:=round(PDest[x].rgbBlue+(PSource[x].rgbBlue-PDest[x].rgbBlue)*trans);
                if lti>255 then lti:=255 else if lti<0 then lti:=0;
                PDest[x].rgbBlue:=lti;
              end;
            end;
            //выхлоп - полупрозрачный текст наложен на Bitmap
            CanvasOut.CopyRect(Rect(TextPosX,TextPosY,TextPosX+TextW,TextPosY+TextH), BmpBuff.canvas, Rect(0,0,BmpBuff.Width,BmpBuff.Height));
          finally
            BmpBuff.Free;
          end;
        end;
         
         //----------------------------------------------------------
        // Наложить полу-прозрачный текст на Jpeg - центр управления
        procedure TextToBitmap(Text:String; JpgInOut:TJPEGImage; FontSize:Byte; TextColor:TColor; Transparency:Byte; TextAlign,TextValign:TAlign; TextLeft,TextTop:Integer);
        var BmpToFinish, BmpText, bmp_text_rgb: TBitmap;
        begin
          BmpToFinish:=TBitmap.Create;
          BmpText:=TBitmap.Create;
          bmp_text_rgb:=TBitmap.Create;
          try
         
            //jpg2bmp
            BmpToFinish.Width:=JpgInOut.Width;
            BmpToFinish.Height:=JpgInOut.Height;
            BmpToFinish.Canvas.StretchDraw(BmpToFinish.Canvas.Cliprect, JpgInOut);
         
            BmpToFinish.PixelFormat:=pf32bit;
            BmpText.PixelFormat:=pf32bit;
            bmp_text_rgb.PixelFormat:=pf32bit;
         
            //настройка шрифта
            BmpText.Canvas.Font.Size:=FontSize;//размер шрифта
            BmpText.Canvas.Font.Color:=rgb(Transparency,Transparency,Transparency); //прозрачность текста 0 - полная прозрачность
            BmpText.Canvas.Font.Name:='Arial';
         
            BmpText.Width:=BmpText.Canvas.TextWidth(Text)+4;//отступы текста - 2 px
            BmpText.Height:=BmpText.Canvas.TextHeight(Text)+4;//отступы текста - 2 px
            bmp_text_rgb.Width:=BmpText.Width;
            bmp_text_rgb.Height:=BmpText.Height;
         
            bmp_text_rgb.Canvas.Brush.Color:=TextColor; //цвет текста
            bmp_text_rgb.Canvas.FillRect(bmp_text_rgb.Canvas.ClipRect);
         
            BmpText.Canvas.Brush.Color:=clBlack;
            BmpText.Canvas.FillRect(BmpText.Canvas.ClipRect);
         
        //    BmpText.Canvas.Brush.Color:=clWhite; //- invert - пример :)
         
            //наложить текст
            BmpText.Canvas.TextOut(2,2,Text);//отступы текста - 2 px
            //создать канал прозрачности тексту
            BuildTextBmp(bmp_text_rgb,BmpText,BmpText);
         
            //подготовка выравнивания текста alRight, alBottom, alClient=center.//знаю, не дело так юзать alClient - сделай правильней! :)
            case TextValign of
              alBottom: TextTop:=BmpToFinish.Height-BmpText.Height+TextTop;
              alClient: TextTop:=(BmpToFinish.Height div 2)-(BmpText.Height div 2)+TextTop;
            end;
            case TextAlign of
              alRight: TextLeft:=BmpToFinish.Width-BmpText.Width;
              alClient: TextLeft:=(BmpToFinish.Width div 2)-(BmpText.Width div 2)+TextLeft;
            end;
         
            //смешать bmp_текст с фоном
            BlendBitmap_GDI(BmpToFinish.Canvas,BmpText,TextLeft,TextTop);
         
            //конвертировать готовый микс из bmp_in в jpg
            JpgInOut.Assign(BmpToFinish);
            JpgInOut.CompressionQuality:=100;
            JpgInOut.Compress;
         
          finally
           BmpToFinish.Free;
           BmpText.Free;
           bmp_text_rgb.Free;
          end;
        end;
         
        //
        // Наложение полу-прозрачного текста на Jpg
        //==============================================================================
      Альберт Эйнштейн: Жизнь отдельного человека имеет смысл лишь в той степени, насколько она помогает сделать жизни других людей красивее и благороднее.

      Освобожденная энергия атомного ядра многое поставила под сомнение, в том числе и наш образ мысли. Если человек так и не сможет думать по-новому, мы неизбежно будем двигаться навстречу беспрецедентной катастрофе.
      1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script Execution time: 0,0709 ]   [ 15 queries used ]   [ Generated: 18.11.17, 12:19 GMT ]