Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[98.80.143.34] |
|
Сообщ.
#1
,
|
|
|
Наложение полупрозрачного текста на Jpeg
Несколько раз уж требовалась внятная функция, для наложения полу-прозрачного текста на jpg. Очень досадно, что в DRKB информации по теме нет. На сей раз перелопатив несколько исходников(в инэте бродит с внесёнными порожняками), сварганил работающий вариант. Мне хватает, надеюсь и другим поможет. { ================================================================================ Наложение полу-прозрачного текста на 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 //============================================================================== |