PDA

Ver la Versión Completa : Necesito componente que imprima imagenes PNG


rufo
20-01-2010, 16:51:28
Hola amigos he estado buscando en todo el foro un componente que me permita imprimir imagenes PNG con su transparencia Alpha ya que tengo los componentes PNGcomponents pero no hay un componente que me imprima dichas imagenes ya que cuando las quiero imprimir me manda un fondo negro ya que estoy haciendo credenciales y quiero imagenes sin fondo blanco, bueno espero que me auxilien y gracias de antemano.

Uso delphi 5 o haber que me recomiendan ustede y gracias de nuevo.

delphi.com.ar
20-01-2010, 17:36:34
Para cargar este tipo de archivos, respetando el alpha channel en Win32 utilizo la librería pngImage (http://pngdelphi.sourceforge.net/). Lo interesante es que se registra como un TGraphic, y puedes utilizarlo en cualquier tipo de componente que utilice un TPicture, incluyendo QuickReports. La mala noticia que tengo es que acabo de hacer una prueba y veo que QuickReports pone todo lo que tiene Alpha en negro, así que se me ocurre preguntarte:

¿Este gráfico tendrá tranparencia sobre algo sólido?... porque de no ser así, lo que te va a convenir es trabajar con BMP de fondo blanco, ya que en la impresora el blanco no se imprime. Al decir esto no digo que tus imágenes originariamente tengan que tener fondo blanco, sino que te encargues de copiar y hacer la composición "a mano" de las imágenes, por ejemplo:


function Flatten(AGraphic: TGraphic; ABackColor: TColor = clWhite): TBitmap;
begin
Result := TBitmap.Create;
with Result do
begin
Width := AGraphic.Width;
Height := AGraphic.Height;

Canvas.Brush.Color := ABackColor;
Canvas.FillRect(Rect(0, 0, Width, Height));

Canvas.Draw(0, 0, AGraphic);
end;
end;


Saludos!

rufo
20-01-2010, 17:41:58
Si de hecho si tengo que imprimir con un colo solido de fondo.

delphi.com.ar
20-01-2010, 17:46:13
Si de hecho si tengo que imprimir con un colo solido de fondo.
Si es un color sólido puedes utilizar la función que escribí para este hilo, si se trata de un solo color simplemente como está utilizando el segundo parámetro de ésta. Si lo dibujas sobre otra imagen, con el mismo criterio puedes introducir esta imagen dentro de la otra antes, utilizando los métodos Draw, CopyRect o bien la winapi StretchBlt.

Si quieres te armo un ejemplito.

Saludos!

rufo
20-01-2010, 17:58:09
Gracias pero la verdad ando un poco verde en esto y si me pudieras explicar en que parte del reporte lo pongo el codigo que escribiste te lo agradeceria muchisimo.:o

delphi.com.ar
20-01-2010, 18:11:42
Ok!.. nunca me confirmaste si se trata de un QuickReports, pero supongo que si:

Las bandas tienen un evento llamado BeforePrint, si esta imagen cambia cada vez que se reimprime la banda, este sería el lugar, pero si no cambia nunca en todo el reporte, puedes asignar el gráfico cuando lo creas o en el evento BeforePrint del reporte, por ejemplo:


procedure TrptTarjeta.QuickRepBeforePrint(Sender: TCustomQuickRep;
var PrintReport: Boolean);
var
P: TPicture;
begin
if FileExists(ChangeFileExt(Application.ExeName, '.bmp')) then
qriLogo.Picture.LoadFromFile(ChangeFileExt(Application.ExeName, '.bmp'))

else if FileExists(ChangeFileExt(Application.ExeName, '.png')) then
begin
P := TPicture.Create;
try
P.LoadFromFile(ChangeFileExt(Application.ExeName, '.png'));
qriLogo.Picture.Assign(Flatten(P.Graphic));
finally
P.Free;
end;
end;
end;



Faltaría fundir la imagen sobre otra de ser necesario.

Saludos!

rufo
20-01-2010, 18:43:47
Gracias amigo pero no me funde la imagen me sigue mostrando el fondo negro y si uso QuickReports, primero lo puse en BeforePrint del reporte y no paso nada y despues lo puse en la banda de DetailBand y nada entonces que estare haciendo mal.

delphi.com.ar
20-01-2010, 19:04:03
Pues... ese código lo escribí para vos, pero sobre un reporte existente.. lo probé y por lo menos en la pantalla lo muestra bien!... y de casualidad elegí un repote que imprime tarjetas de banda magnéticas :p

Porque no subes algo de código así lo vemos!

Saludos!

rufo
20-01-2010, 19:18:32
Ok

Para buscar la imagen pongo este codigo

procedure TBuscar_foto.Button1Click(Sender: TObject);
begin
if openpicturedialog1.Execute then
begin
image1.Picture.LoadFromFile(openpicturedialog1.filename);
edit1.Text:=openpicturedialog1.filename;
end;
end;
Y para mandar a imprimir la foto es este codigo

procedure TBuscar_foto.Button2Click(Sender: TObject);
begin
with Fr_foto do
begin
qrimage1.Picture.LoadFromFile(openpicturedialog1.FileName);
quickrep1.preview;
end;
end;
Y pongo tu codigo que me diste


implementation
uses QRPrntr;
{$R *.DFM}
function Flatten(AGraphic: TGraphic; ABackColor: TColor = clWhite): TBitmap;
begin
Result := TBitmap.Create;
with Result do
begin
Width := AGraphic.Width;
Height := AGraphic.Height;
Canvas.Brush.Color := ABackColor;
Canvas.FillRect(Rect(0, 0, Width, Height));

Canvas.Draw(0, 0, AGraphic);
end;
procedure TFR_foto.DetailBand1BeforePrint(Sender: TQRCustomBand;
var PrintBand: Boolean);
var
P: TPicture;
begin
if FileExists(ChangeFileExt(Application.ExeName, '.bmp')) then
qrimage1.Picture.LoadFromFile(ChangeFileExt(Application.ExeName, '.bmp'))

else if FileExists(ChangeFileExt(Application.ExeName, '.png')) then
begin
P := TPicture.Create;
try
P.LoadFromFile(ChangeFileExt(Application.ExeName, '.png'));
qrimage1.Picture.Assign(Flatten(P.Graphic));
finally
P.Free;
end;
end;

end;

end;
end.


Entonces es asi como lo estoy programando ahorita.

delphi.com.ar
20-01-2010, 19:25:43
Pero pegaste mi código tal cual!... tenías que adaptarlo a tu necesidad!.. fíjate que mi código lo que hace es intentar cargar un archivo bmp o png que se llame igual que el ejecutable.

Por lo que entiendo tu necesitas hacer algo como:

procedure TBuscar_foto.Button2Click(Sender: TObject);
var
P: TPicture;
B: TBitmap;
begin
with Fr_foto do
begin
P := TPicture.Create;
try
P.LoadFromFile(openpicturedialog1.FileName);
B := Flatten(P.Graphic);
try
qrimage1.Picture.Assign(B);
finally
B.free;
end;
quickrep1.preview;
finally
P.Free;
end;
end;
end;

No utilizando los eventos BeforePrint en este caso.

Saludos!

rufo
20-01-2010, 19:41:36
Sorry tienes razon pero ya lo puse y tal como ahorita me acabas de decir y resulta que ahora el PNG sale con fondo blanco, hijole esta muy estresante esto de Imagenes PNG, no hay un componente que se complemente en QReport.

delphi.com.ar
20-01-2010, 19:49:11
Sorry tienes razon pero ya lo puse y tal como ahorita me acabas de decir y resulta que ahora el PNG sale con fondo blanco, hijole esta muy estresante esto de Imagenes PNG, no hay un componente que se complemente en QReport.
Fíjate que en la función Flatten el segundo parámetro indica con que color deseas llenar el fondo, y si lo quisieras llenarlo con otra imagen, tendrías que copiar una sobre otra!

Saludos!

rufo
20-01-2010, 20:08:45
Disculpa mi torpeza pero me puedes decir como lo hago, ya que es una imagen que tengo de fondo y despues sigue la foto.

la parte que mencionas que debo cambiar seria esta


function Flatten(AGraphic: TGraphic; ABackColor: TColor = clyellow): TBitmap;


o estoy perdido:(

delphi.com.ar
20-01-2010, 21:16:15
No me refería al valor por defecto, sino que al llamar la función la llames:

qrimage1.Picture.Assign(Flatten(P.Graphic, clYellow));



Por otro lado, si quieres tener una imagen de fondo, podría ser algo así

procedure TBuscar_foto.Button2Click(Sender: TObject);
var
imgBack: TBitmap;
imgLogo: TPNGObject;
begin
with Fr_foto do
begin
imgBack := TBitmap.Create;
try
{ Podes cargarlos de un archivo, de recursos, copiarlo de algo previamente cargado }
imgBack.LoadFromFile('....fondo.bmp');

imgLogo := TPNGObject.Create;
try
imgLogo.LoadFromFile(openpicturedialog1.FileName);
{ en la posición que desees ponerlo }
imgBack.Canvas.Draw(10, 10, imgLogo);

qrimage1.Picture.Assign(imgBack);
quickrep1.preview;
finally
imgLogo.Free;
end;
finally
imgBack.Free;
end;
end;
end;

rufo
20-01-2010, 22:14:57
Ok mira ya puse el codigo que me diste pero me marca error TPNGObject dice que no lo identifica a que se debera este error
o que estoy haciendo mal.:confused:

delphi.com.ar
20-01-2010, 22:28:34
Si utilizas como yo la librería PNGImage tienes que agregar el uso de la unit pngimage en donde utilices esa clase. Sino cambia la clase a un TPicture que anteriormente te funcionó, con la salvedad que luego tienes que asignar la propiedad Graphic de esta.

Saludos!

rufo
20-01-2010, 22:54:34
Gracias amigo ya quedo ahora solo me falta que la foto salga en medio del fondo, pero voy a checarlo haber como le hago

delphi.com.ar
20-01-2010, 23:21:31
Gracias amigo ya quedo ahora solo me falta que la foto salga en medio del fondo, pero voy a checarlo haber como le hago
Es tan simple como cambiar estas coordenadas: imgBack.Canvas.Draw(10, 10, imgLogo); por las coordenadas de tu qrimage1, salvo que se este escalando, en ese caso vas a tener que jugar un poco con esos dos valores.

Saludos!

rufo
21-01-2010, 00:09:45
Gracias nuevamente pero ya he jugado con esos valores que me dices pero sigo sin tener resultado.

rufo
21-01-2010, 00:42:16
Anexo mi programa para que veas como esta y le eches una miradita para ver si estoy bien y gracias de antemano.

delphi.com.ar
21-01-2010, 14:24:38
Gracias nuevamente pero ya he jugado con esos valores que me dices pero sigo sin tener resultado.
Acabo de ver tu programita, y observo que funciona perfecto!... no será que estas moviendo valores tan chicos que no logras observar el cambio?.. Prueba algo como:
imgBack.Canvas.Draw(100, 100,imgLogo);

A mi me funciona perfecto!

rufo
21-01-2010, 16:55:54
Gracias amigo ya lo intente moviendo estos valores y no me centra la foto, mira te anexo las imagenes de como sale y como quisiera que saliera, espero tu comentario y de nuevo gracias.

delphi.com.ar
21-01-2010, 22:12:35
Rufo, por favor no lo tomes a mal, pero si cada duda por más mínima que sea no intentas resolverla investigando un poco, no imagino como harás para completar el proyecto. Es muy importante investigar, comprender y razonar las soluciones posibles. Tómalo como una simple recomendación.

La solución que se me ocurre, si el fondo no se imprime en el tamaño esperado, edítalo como para que así sea. Siempre va a ser mejor la forma de escalar imágenes de algún software específico que la que puedes obtener con las herramientas básicas de dibujo y como tu fondo no es algo dinámico, es conveniente que así sea. Para centrar la otra imagen sobre esta, puedes hacer algo tan simple como esto:


imgBack.Canvas.Draw((imgBack.Width - imgLogo.Width) div 2,
(imgBack.Height - imgLogo.Height) div 2,
imgLogo);


Saludos!