 |
Club Builder Foro de C++Builder en español
|
| Ver tema anterior :: Ver tema siguiente |
| Autor |
Mensaje |
Isa1976 Lt Cmdr


Registrado: 23 Nov 2005Mensajes: 104
|
Publicado: Dom 01 Jul, 2007 8:39 pm Asunto: Teniendo un canvas, poner otro encima semitransparente. |
|
|
Tengo un cavas, con una imagen cargada de un paisaje. Tengo otro canvas con un dibjujo de un logo.
Como puedo poner el logo enima del paisaje pero que se siga viendo el paisaje?, de forma semitransparente?.
he encontrado este codigo, pero no he encontrado un ejemplo, y la verdad no se por donde cojerlo... (por ejemplo, no se que es HDC)
| Código: | void DrawSemiTransparentBitmap(HDC hDstDC, int x, int y, int nWidth, int nHeight, HDC hSrcDC, int xSrc, int ySrc)
{
HDC hdcCompatible = CreateCompatibleDC(hDstDC);
HBITMAP hBmp = CreateCompatibleBitmap(hDstDC, nWidth, nHeight);
HGDIOBJ hBitmapOld = SelectObject(hdcCompatible, hBmp);
RECT rc = { 0, 0, nWidth, nHeight };
HBRUSH hBrush = CreateSolidBrush(RGB(0x7F, 0x7F, 0x7F));
FillRect(hdcCompatible, &rc, hBrush);
DeleteObject(hBrush);
BitBlt(hDstDC, x, y, nWidth, nHeight, hdcCompatible, 0, 0, SRCAND);
SelectObject(hdcCompatible, hBitmapOld);
DeleteObject(hBmp);
DeleteDC(hdcCompatible);
BitBlt(hDstDC, x, y, nWidth, nHeight, hSrcDC, 0, 0, SRCPAINT);
} |
Si a alguien le suena algo de esto, solo pido como teniendo dos canvas puedo llamar a esta función.
MUCHAS GRACIAS!!!! |
|
| Volver arriba |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Lun 02 Jul, 2007 4:55 am Asunto: |
|
|
Tal como está a mi no me funciona..
Si quieres algo similar y que funciona prueba con la siguiente rutina:
| Código: | void DrawSemiTransparentBitmap(HDC hDstDC, int x, int y, int nWidth,
int nHeight, HDC hSrcDC, int xSrc, int ySrc, BYTE op=50)
{
BLENDFUNCTION bf;
ZeroMemory(&bf, sizeof(bf));
bf.BlendOp = AC_SRC_OVER;
bf.SourceConstantAlpha = MulDiv(op, 255, 100);
AlphaBlend(hDstDC, x, y, nWidth, nHeight,
hSrcDC, xSrc, ySrc, nWidth, nHeight, bf);
} |
He mantenido los mismos argumentos, pero añadiendo un nuevo parámetro opcional donde le indicamos el porcentaje de opacidad.
IMPORTANTE: Para poder usar la función AlphaBlend del API tenemos que añadir "msimg32.lib" a nuestro proyecto. La podemos encontrar en el subdirectorio "\Lib\Psdk\" donde tengamos instalado nuestro BCB.
Y para probar la rutina podemos añadir 2 TImage, en el primero que usaremos como destino cargamos el paisaje y en el segundo el logo:
| Código: | Image1->Picture->LoadFromFile("d:\\imagen.bmp");
Image2->Picture->LoadFromFile("d:\\logo.bmp");
DrawSemiTransparentBitmap(Image1->Canvas->Handle, 512, 10, 78, 118, Image2->Canvas->Handle, 0, 0);
Image1->Update(); |
Si miras más a fondo la función AlphaBlend veras que incluso te permitiría definir el nivel de transparencia de cada pixel.. |
|
| Volver arriba |
|
 |
Isa1976 Lt Cmdr


Registrado: 23 Nov 2005Mensajes: 104
|
Publicado: Lun 02 Jul, 2007 9:10 pm Asunto: Bien... |
|
|
Hola,
muchas gracias por contestar, la verdad es que ya me funciona, pero solo con algunas imagines.
te pongo un ejemplo:
| Código: | // Declaracion
Graphics::TBitmap *b = new Graphics::TBitmap();
b->PixelFormat=pf24bit;
b->Width=Screen->Width;
b->Height=Screen->Height;
Graphics::TBitmap *Rectangulo = new Graphics::TBitmap();
Rectangulo->PixelFormat=pf24bit;
Rectangulo->Width=100;
Rectangulo->Height=200;
// Se prepara un rectangulo azul
Rectangulo->Canvas->Brush->Color = clBlue;
Rectangulo->Canvas->FillRect(Rectangulo->Canvas->ClipRect);
Src=Rect(0,0,Rectangulo->Width,Rectangulo->Height);
Dest=Rect(200,200,300,400);
// se copia el rectangulo azul en b
b->Canvas->CopyRect(Dest, Rectangulo->Canvas, Src);
// se pega al 50% en b
SemiTransparent(b->Canvas->Handle, 20, 20, 300, 300, Rectangulo->Canvas->Handle, 0, 0, 50); |
Al copiar con copyrect funciona bien, pero el Semitransparent no.
He estado probando con algunas fotos y si funcina, con otras no, por ejemplo si abro el paint y creo un dibujo tampoco me funciona, pero si cojo una foto si me deja.
Creo que va a ser problema de color o algo asi... en realidad no tengo mucha idea de por que sucede esto con algunas imagenes,
¿puede ser que haya que dar algún tipo de formato al canvas antes?
MUCHAS GRACIAS DE NUEVO! |
|
| Volver arriba |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Lun 02 Jul, 2007 10:01 pm Asunto: |
|
|
En el caso del ejemplo que pones ocurre porque estas especificando un tamaño de imagen más grande que el tamaño real del bitmap de origen.
SemiTransparent(b->Canvas->Handle, 20, 20, 300, 300, Rectangulo->Canvas->Handle, 0, 0, 50);
Si cambiamos estos dos valores al tamaño máximo o menor de la imagen origen funciona..
Si quieres pegar siempre la imagen origen completa sobre la destino sin preocuparte del tamaño podriamos simplificar un poco la rutina:
| Código: | void SemiTransparent(Graphics::TBitmap* dst, int x, int y,
Graphics::TBitmap* src, BYTE op=50)
{
BLENDFUNCTION bf;
ZeroMemory(&bf, sizeof(bf));
bf.BlendOp = AC_SRC_OVER;
bf.SourceConstantAlpha = MulDiv(op, 255, 100);
AlphaBlend(dst->Canvas->Handle, x, y, src->Width, src->Height,
src->Canvas->Handle, 0, 0, src->Width, src->Height, bf);
} |
Y la forma de usarla teniendo en cuenta tu ejemplo:
| Código: | SemiTransparent(b, 20, 20, Rectangulo, 50); |
De todas formas si aun con eso te sigue fallando y para localizar mejor el problema si quieres pásame un par de imágenes con las que te falle y el código que usas para cargarlas etc..
leosoftware ARROBA gmail PUNTO com |
|
| Volver arriba |
|
 |
Isa1976 Lt Cmdr


Registrado: 23 Nov 2005Mensajes: 104
|
Publicado: Mar 03 Jul, 2007 12:51 pm Asunto: |
|
|
hola!
Gracias, tenias razón, era problema de tamaño, y gracias también por la nueva función, que es la que voy a utilizar, ya que voy a copiar las imagenes completas.
Si quiero poner texto SemiTransparente, como puedo utilizar esta misma función. Existe esa posibilidad?
Yo pego texto con borde de la siguiente manera, y me gustaria hacerlo dándole un nivel de transparencia:
| Código: | SetBkMode(b->Canvas->Handle, TransparentColor);
SetTextAlign(b->Canvas->Handle, TA_BASELINE);
b->Canvas->Font = FontDialog1->Font;
b->Canvas->Font->Size = 15;
BeginPath(b->Canvas->Handle);
b->Canvas->TextOut(100,100,Edit1->Text);
EndPath(b->Canvas->Handle);
b->Canvas->Brush->Color = clAqua;
b->Canvas->Brush->Style = bsSolid;//bsDiagCross;
b->Canvas->Pen->Style = psSolid;
b->Canvas->Pen->Width = 1;
b->Canvas->Pen->Color = clBlue;
StrokeAndFillPath(b->Canvas->Handle); |
Aviso a quien vaya a utilizar la función AlphaBlend:
si no os funciona hay que poner ::AlphaBlend
Y otra cosa, si tomais las imagenes de un TImage, este tiene que tener cargada un BMP, si no no funciona.
MUCHAS GRACIAS[/code] |
|
| Volver arriba |
|
 |
_Leo Site Admin

Registrado: 11 Ago 2002Mensajes: 1875Ubicación: Lanzarote - Islas Canarias (España)
|
Publicado: Mar 03 Jul, 2007 6:44 pm Asunto: |
|
|
Podrías hacerlo usando la misma función, creas un bitmap en el que escribes el texto y lo vuelcas como con la anterior.. El único detalle diferente seria utilizar la posibilidad que nos da esta función para definir el nivel de transparencia de cada pixel individual, para así hacer totalmente invisible la parte exterior al texto...
A ver si te sirve esta función:
| Código: | void SemiTransparentText(Graphics::TBitmap* dst, int x, int y,
String text, String fontName, int fontSize, TColor color,
BYTE op=50, int borderWidth=0, TColor borderColor=clNone)
{
Graphics::TBitmap* bmp = new Graphics::TBitmap;
bmp->PixelFormat = pf32bit;
bmp->Canvas->Font->Name = fontName;
bmp->Canvas->Font->Size = fontSize;
bmp->Canvas->Brush->Color = color;
bmp->Canvas->Pen->Width = borderWidth;
bmp->Canvas->Pen->Color = borderColor;
bmp->Width = bmp->Canvas->TextWidth(text);
bmp->Height = bmp->Canvas->TextHeight(text);
// Marcamos todo el fondo con un valor que nos sirve
// para saber los pixels que seran transparentes
DWORD* ptr = (DWORD*)bmp->ScanLine[bmp->Height-1];
for (int i=0; i <bmp>Height * bmp->Width; i++)
ptr[i] = 0x11000000;
BeginPath(bmp->Canvas->Handle);
SetBkMode(bmp->Canvas->Handle, TRANSPARENT);
bmp->Canvas->TextOut(0, 0, text);
EndPath(bmp->Canvas->Handle);
if (borderWidth)
StrokeAndFillPath(bmp->Canvas->Handle);
else
FillPath(bmp->Canvas->Handle);
// Modificamos el canal alfa del bitmap..
ptr = (DWORD*)bmp->ScanLine[bmp->Height-1];
for (int i=0; i <bmp>Height * bmp->Width; i++)
ptr[i] = (ptr[i] & 0xFF000000) ? 0 : ptr[i] | 0xFF000000;
// Volcamos el bitmap con el texto sobre el bitmap destino
BLENDFUNCTION bf = {0, 0, MulDiv(op, 255, 100), AC_SRC_ALPHA};
AlphaBlend(dst->Canvas->Handle, x, y, bmp->Width, bmp->Height,
bmp->Canvas->Handle, 0, 0, bmp->Width, bmp->Height, bf);
} |
Y unos ejemplos de uso:
- Con el borde blanco y el interior rojo:
| Código: | SemiTransparentText(Image1->Picture->Bitmap, 10, 10,
"Prueba", "Arial Black", 72, clRed, 50, 3, clWhite); |
- De color azul y sin borde:
| Código: | SemiTransparentText(Image1->Picture->Bitmap, 10, 10,
"Prueba", "Arial Black", 72, clBlue, 50); |
 |
|
| Volver arriba |
|
 |
Isa1976 Lt Cmdr


Registrado: 23 Nov 2005Mensajes: 104
|
Publicado: Mar 03 Jul, 2007 8:23 pm Asunto: MUCHAS GRACIAS |
|
|
Todo funciona de maravilla!
Solo me queda dar las gracias...
¡¡¡¡¡¡MUCHAS GRACIAS!!!!! |
|
| Volver arriba |
|
 |
vizca321 Lt


Registrado: 06 May 2008Mensajes: 83Ubicación: Mexico
|
Publicado: Sab 16 Ene, 2010 12:56 am Asunto: |
|
|
Primero que nada saludos a ambos
Mi problemas es casi el mismo pero con dos componentes diferentes con el TWindowsMediaPlayer y un TFIleListBox, el contenedor seria el TWindowsMediaPlayer
O y disculpen mi ignoracia me podrian decir como incluir la libreria "msimg32.lib" |
|
| Volver arriba |
|
 |
|
|
No puedes publicar temas nuevos en este foro No puedes responder a temas en este foro No puedes editar tus mensajes en este foro No puedes borrar tus mensajes en este foro No puedes votar en las encuestas de este foro
|
© 2002–2026 Club Builder · Funciona con phpBB.
|