Delphi - Unir imagenes

 
Vista:
sin imagen de perfil
Val: 65
Oro
Ha mantenido su posición en Delphi (en relación al último mes)
Gráfica de Delphi

Unir imagenes

Publicado por E.T. (1244 intervenciones) el 13/03/2007 19:50:15
Hola. Deseo unir dos o más imagenes, algo como una panorámica, supongamos que tengo 2 TBitmap y deseo unirlos y estos dos asignarlos, ya unidos, a un TImage, si alguien sabe como hacerle, gracias.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
sin imagen de perfil
Val: 65
Oro
Ha mantenido su posición en Delphi (en relación al último mes)
Gráfica de Delphi

RE:Unir imagenes

Publicado por E.T. (1244 intervenciones) el 16/03/2007 19:40:26
Bueno ya resolví mi duda, con un poco de investigación, ahí les va, como quiera a alguien le es util

MyRect:=Rect(0,0,Image.Width,Image.Height);
MyOther:=Rect(0,MyOther.Bottom,Image.Width,Image.Height+y_last);

y_last Se inicializa en 0

"MyRect" y "MyOther" son variables de tipo TRect, "Image" es un TBitmap; asi que el primer rectángulo tiene dimensión desde 0,0 (coordenadas) hasta x,y (tambien coordenadas que son las dimensiones de la imagen) y MyOther tiene desde 0,variable(la cual aumenta cada vez que agregamos una imagen) hasta x,y+Variable (la cual es la altura de la nueva imagen)

NOTA: yo no aumento el ancho de la imagen ya que todas la imagenes que adjunto tienen la misma anchura, cada quien lo puede adaptar a su gusto

Bien, ahora esto se puede hacer de dos formas de forma interna o ir viendo un preview de las imagenes pegadas, primero veamos la forma interna que es la más facil

En el siguiente código inicializamos "y_last" creamos un TBitmap y lo asignamos a la variable imageholder, la siguiente línea es opcional para ustedes, ya que yo necesito imagenes en blanco y negro

procedure TForm1.FormCreate(Sender: TObject);
begin
y_last:=0;
Imageholder:=TBitmap.Create;
imageholder.PixelFormat:=pf8bit;
end;

El siguiente código va dentro del click de un botón llamado GoAcquire

procedure TForm1.GoAcquireClick(Sender: TObject);
var
SelectedSource: Integer;
begin
if Twain.LoadLibrary then
begin
Twain.SourceManagerLoaded := TRUE;
SelectedSource := 1;//Twain.SelectSource;{ En esta linea la parte que no está en comentarios toma de la lista de fuentes de imagenes la segunda opción, la cual es por medio del asistente de windows,esta lista varía segun los programas de escaneo que tengamos así como el número de escaneres que tengamos, la linea que está entre comentarios abre una lista de fuentes de imagenes, podemos seleccionar la que queramos }

if SelectedSource <> -1 then
begin
Twain.Source[SelectedSource].Loaded := TRUE;
Twain.Source[SelectedSource].TransferMode := ttmMemory;
Twain.Source[SelectedSource].ShowUI:=false;{Como seleccionamos como fuente, en este ejemplo, el asistente de windows ocultamos la interfáz con ella, esta linea se puede omitir para seleccionar entre varias opciones como:resolución, color o b/n, etc..; Yo la omito porque las imagenes que adquiero las necesito en b/n}
Twain.Source[SelectedSource].Enabled := TRUE;
end
end
else
showmessage('Twain is not installed.');
end;

El siguiente código ve dentro del evento "TwainTwainAcquire" del componente "TDelphiTwain"

procedure TForm1.TwainTwainAcquire(Sender: TObject; const Index: Integer;
Image: TBitmap; var Cancel: Boolean);
begin
MyRect:=Rect(0,0,Image.Width,Image.Height);
MyOther:=Rect(0,MyOther.Bottom,Image.Width,Image.Height+y_last);

imageholder.Width:=Image.Width;{ "ImageHolder" en este caso es un TBitmap }
imageholder.Height:=image.Height+y_last;
ImageHolder.Canvas.BrushCopy(MyOther,Image,MyRect,clNone);
y_last:=MyOther.Bottom;
end;

Ahora, cada vez que ejecutemos el código de arriba (en mi caso cada vez que se escanee una imagen, al darle click al botón GoAcquire) se irá formando una tira de imagenes; se puede sustituir el evento "TwainTwainAcquire" por el código en un botón, y la variable "image" (del mismo evento, yo no la declaré) cambiarla por un TImage, pero no se puede usar directamente hay que usar sus propiedades de "Image.Picture.Bitmap" para que funcione, y cada vez que se vaya a agregar una imagen en otro botón agregar el código para que el TImage "Image" cargue una imagen antes de pegar

Ahora, en otro botón ponemos el siguiente código; "Img" es una variable tipo TJPEGImage

procedure TForm1.Button1Click(Sender: TObject);
begin
img:=TJPEGImage.Create;
Img.CompressionQuality:=60;{Esta linea y la siguiente son opcionales, por medio de ellas pueden comprimir la imagen que hemos unido, va desde 1 hasta 100}
Img.Compress;
Img.Assign(imageholder);
Img.SaveToFile('Imagen.jpg');{Por último la guardamos en disco duro, podemos especificar el directorio de destino, yo lo hago donde está la aplicación}
Img.Free;
end;

En la siguiente respuesta pongo cono hacerlo con preview
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil
Val: 65
Oro
Ha mantenido su posición en Delphi (en relación al último mes)
Gráfica de Delphi

RE:Unir imagenes

Publicado por E.T. (1244 intervenciones) el 16/03/2007 20:04:34
Esto es un poco más complejo, voy a explicar por que:

Como usamos un TImage y su propiedad canvas, al momento de darle una imagen a ésta su tamaño queda fijo y si queremos añadir la siguiente imagen no podremos verla ya que quedará fuera de los limites, por lo tanto tenemos que destruir el TImage y crearlo de nuevo con un nuevo tamaño, que sería el que tiene actualmente más la altura de la nueva imagen, les recuerdo que las imagenes que yo utilizo son escaenadas y por lo tanto tiene siempre las mismas longitudes de altura y anchura.

Ahí va pues:

En este caso "ImageHolder" no lo declaramos ya que lo creamos en tiempo de ejecución

procedure TForm1.FormCreate(Sender: TObject);
begin
y_last:=0;
end;

Tenemos el mismo evento del boton para escanear que en la anterior respuesta

procedure TForm1.GoAcquireClick(Sender: TObject);
var
SelectedSource: Integer;
begin
if Twain.LoadLibrary then
begin
Twain.SourceManagerLoaded := TRUE;
SelectedSource := 1;//Twain.SelectSource;{ En esta linea la parte que no está en comentarios toma de la lista de fuentes de imagenes la segunda opción, la cual es por medio del asistente de windows,esta lista varía segun los programas de escaneo que tengamos así como el número de escaneres que tengamos, la linea que está entre comentarios abre una lista de fuentes de imagenes, podemos seleccionar la que queramos }

if SelectedSource <> -1 then
begin
Twain.Source[SelectedSource].Loaded := TRUE;
Twain.Source[SelectedSource].TransferMode := ttmMemory;
Twain.Source[SelectedSource].ShowUI:=false;{Como seleccionamos como fuente, en este ejemplo, el asistente de windows ocultamos la interfáz con ella, esta linea se puede omitir para seleccionar entre varias opciones como:resolución, color o b/n, etc..; Yo la omito porque las imagenes que adquiero las necesito en b/n}
Twain.Source[SelectedSource].Enabled := TRUE;
end
end
else
showmessage('Twain is not installed.');
end;

Ahora viene el cambio dentro del evento TwainAcquire, declaramos dos variables enteras: x,y

procedure TForm1.TwainTwainAcquire(Sender: TObject; const Index: Integer;
Image: TBitmap; var Cancel: Boolean);
var x,y:integer;
begin

inc(n);//n lo inicializamos en 0 al crearse la aplicación
MyRect:=Rect(0,0,Image.Width,Image.Height);
MyOther:=Rect(0,MyOther.Bottom,Image.Width,Image.Height+y_last);

{Primero checamos que el componete TImage que necesitamos exista, y si no lo creamos, en la siguiente sentencia "if"}

If (FindComponent('ImageHolder'))=nil then begin
TImage.Create(Self).Name:='ImageHolder';
TImage(FindComponent('ImageHolder')).Top:=104;
TImage(FindComponent('ImageHolder')).Left:=24;
TImage(FindComponent('ImageHolder')).Width:=Form1.ClientWidth-50;
TImage(FindComponent('ImageHolder')).Height:=Form1.ClientHeight-129;
TImage(FindComponent('ImageHolder')).Stretch:=true;
TImage(FindComponent('ImageHolder')).Parent:=self;
TImage(FindComponent('ImageHolder')).Anchors:=[akLeft,akTop,akRight,akBottom];
end;

x:=TImage(FindComponent('ImageHolder')).Width;
y:=TImage(FindComponent('ImageHolder')).Height;

{La siguiente linea es para ejecutar el codigo ya que sea la segunda imagen que agregamos}
if n<>1 then begin

TImage(FindComponent('ImageHolder')).Width:=Image.Width;
TImage(FindComponent('ImageHolder')).Height:=y_last;
TImage(FindComponent('ImageHolder')).Stretch:=false;
TImage.Create(Self).Name:='ImageAux';
TImage(FindComponent('ImageAux')).Top:=104;
TImage(FindComponent('ImageAux')).Left:=24;
TImage(FindComponent('ImageAux')).Width:=TImage(FindComponent('ImageHolder')).Width;
TImage(FindComponent('ImageAux')).Height:=TImage(FindComponent('ImageHolder')).Height;
TImage(FindComponent('ImageAux')).Stretch:=true;
TImage(FindComponent('ImageAux')).Parent:=self;
TImage(FindComponent('ImageAux')).Anchors:=[akLeft,akTop,akRight,akBottom];
TImage(FindComponent('ImageAux')).Canvas.BrushCopy(rect(0,0,TImage(FindComponent('ImageHolder')).Width,
TImage(FindComponent('ImageHolder')).Height),
TImage(FindComponent('ImageHolder')).Picture.Bitmap,
rect(0,0,TImage(FindComponent('ImageHolder')).Width,
TImage(FindComponent('ImageHolder')).Height)
,clnone);
TImage(FindComponent('ImageHolder')).Destroy;
If (FindComponent('ImageHolder'))=nil then begin
TImage.Create(Self).Name:='ImageHolder';
//with TImage(FindComponent('ImageHolder')) do begin
TImage(FindComponent('ImageHolder')).Top:=104;
TImage(FindComponent('ImageHolder')).Left:=24;
TImage(FindComponent('ImageHolder')).Width:=TImage(FindComponent('ImageAux')).Width;
TImage(FindComponent('ImageHolder')).Height:=TImage(FindComponent('ImageAux')).Height+image.Height;
TImage(FindComponent('ImageHolder')).Stretch:=true;
TImage(FindComponent('ImageHolder')).Parent:=self;
TImage(FindComponent('ImageHolder')).Anchors:=[akLeft,akTop,akRight,akBottom];
//end;
end;
TImage(FindComponent('ImageHolder')).Canvas.BrushCopy(rect(0,0,TImage(FindComponent('ImageAux')).Width,
TImage(FindComponent('ImageAux')).Height),
TImage(FindComponent('ImageAux')).Picture.Bitmap,
rect(0,0,TImage(FindComponent('ImageAux')).Width,
TImage(FindComponent('ImageAux')).Height)
,clnone);
TImage(FindComponent('ImageAux')).Destroy;
end else begin
TImage(FindComponent('ImageHolder')).Width:=Image.Width;
TImage(FindComponent('ImageHolder')).Height:=y_last;
TImage(FindComponent('ImageHolder')).Stretch:=false;
TImage(FindComponent('ImageHolder')).Height:=(Image.Height+y_last);
end;

TImage(FindComponent('ImageHolder')).Stretch:=false;
TImage(FindComponent('ImageHolder')).Canvas.BrushCopy(MyOther,Image,MyRect,clNone);
y_last:=MyOther.Bottom;

TImage(FindComponent('ImageHolder')).Width:=x;
TImage(FindComponent('ImageHolder')).Height:=y;
TImage(FindComponent('ImageHolder')).Stretch:=true;
end;

Y por último guardamos la imagen

procedure TForm1.Button1Click(Sender: TObject);
begin
img:=TJPEGImage.Create;
Img.CompressionQuality:=60;
Img.Compress;
Img.Assign(TImage(FindComponent('ImageHolder')).Picture.Bitmap);
Img.SaveToFile('Imagen.jpg');
Img.Free;
end;

Hay que tener en cuenta que tenemos un límite de memoria en el TImage para cargar imagenes por lo tanto son limitadas dependiendo del tamaño de las mismas, yo pego imagenes de 1248x1650 y me soporta el TImage alrededor de 5 imagenes, pero de manera interna al dejar el formatpixel en 8 bits guardé una imagen de 1248x23100 sin compresión y me la dejó a un tamaño de 7.5 megas y una con la compresión del 50% de 1248x19800 en 1.74 megas asi que ustedes deciden si comprimen o no.

Si alguien tiene una duda contacteme
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar