Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > C++ Builder
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 12-12-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
Concatenar imagenes y copiar al portapapeles

Hola amigos, estoy intentando concatenar imagenes de diferentes tamaños en un TBitmap y guardarlo en el portapapeles pero no se que hago mal que no se guarda correctamente en el portapapeles y si intento pegarlo por ejemplo en paint me dice "Error al obtener informacion del portapapeles".

Esto es lo que tengo hecho:
Código PHP:
void __fastcall TForm1::CopyCatImagesToClipBoard()
{
   
unsigned int DataHandle;
   
HPALETTE APalette;
   
unsigned short MyFormat;
   
int x=0,y=0;
   
TRect ARectBRect;

   
//Solicito memoria para el bitmap que contendrá el concatenado de imagenes
   
Graphics::TBitmap *FullMap = new (nothrowGraphics::TBitmap();

   if(
FullMap != NULL)
   {
      
Graphics::TBitmap **= new (nothrowGraphics::TBitmap*[CheckListBox->Count];

      if(*
!= NULL)
      { 
//Si se obtuvo memoria correctamente...
         
for(int i=0CheckListBox->Counti++)
         {
            
//Asigno memoria a cada Bitmap que contendrá a cada imagen
            
b[i] = new (nothrowGraphics::TBitmap();

            if(
b[i] != NULL)
            { 
//Si se obtuvo memoria correctamente...
               
try
               {
                  
//Meto cada imagen en su Bitmap
                  
b[i]->LoadFromFile(ChangeFileExt(CheckListBox->Items->Strings[i],".bmp"));

                  
//Le sumo el ancho de la imagen actual a y
                  
+= b[i]->Width;

                  
//Relleno el TRect para la imagen concatenada
                  
ARect.Left 0;
                  
ARect.Top 0;
                  
ARect.Right b[i]->Width;
                  
ARect.Bottom b[i]->Height;

                  
//Relleno el TRect para la imagen actual
                  
BRect.Left x;
                  
BRect.Top 0;
                  
BRect.Right y;
                  
BRect.Bottom b[i]->Height;

                  
// Añado el canvas a la imagen que contendrá el concatenado de imagenes
                  
FullMap->Canvas->CopyRect(BRectb[i]->CanvasARect);

                  
//Le sumo el ancho de la imagen actual a x
                  
+= b[i]->Width;
               }
               catch(...)
               {
                  
//Si huvo algun error libero toda la memoria obtenida y salgo de la funcion
                  
for(int v=0<= iv++)
                     
delete b[v];
                  
delete [] b;
                  
delete FullMap;
                  
FullMap NULL;
                  
Application->MessageBoxA("Hubo un error al copiar las imagenes concatenadas al portapapeles""Error"MB_OK MB_ICONERROR);
               }
               
//Si huvo algun error salgo
               
if(FullMap == NULL)
                  return;
            }else{ 
//Si no se pudo obtener la memoria suficiente...
               //Libero toda la memoria obtenida y salgo de la funcion
               
for(int v=0iv++)
                  
delete b[v];
               
delete [] b;
               
delete FullMap;
               
Application->MessageBoxA("Hubo un error al copiar las imagenes concatenadas al portapapeles""Error"MB_OK MB_ICONERROR);
               return;
            }
         }

         try
         {
            
// generate a clipboard format, with data and palette
            
FullMap->SaveToClipboardFormat(MyFormat,DataHandle,APalette);

            
// save the data to the clipboard using that format and
            // the generated data
            
Clipboard()->SetAsHandle(MyFormat,DataHandle);
         }
         catch(...)
         { 
//Si huvo algun error libero toda la memoria obtenida
            
for(int v=0CheckListBox->Countv++)
               
delete b[v];
            
delete [] b;
            
delete FullMap;
            
FullMap NULL;
            
Application->MessageBoxA("Hubo un error al copiar las imagenes concatenadas al portapapeles""Error"MB_OK MB_ICONERROR);
         }
         
//Si huvo algun error salgo de  la funcion
         
if(FullMap == NULL)
            return;

         
//Libero toda la memoria obtenida
         
for(int i=0;CheckListBox->Counti++)
            
delete b[i];
         
delete [] b;
         
delete FullMap;
      }else{ 
//Si no se pudo obtener la memoria suficiente...
         //Libero toda la memoria obtenida
         
delete FullMap;
         
Application->MessageBoxA("Hubo un error al copiar las imagenes concatenadas al portapapeles""Error"MB_OK MB_ICONERROR);
      }
   }else{
      
Application->MessageBoxA("Hubo un error al copiar las imagenes concatenadas al portapapeles""Error"MB_OK MB_ICONERROR);
   }

¿que me falta para que funcione?
Responder Con Cita
  #2  
Antiguo 12-12-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
al final di con el fallo, el problema era que habia que indicar el ancho y alto del bitmap que contendrá todas las demas imagenes. Ademas me di cuenta que el array de tbitmaps no era necerario asi que uso un solo tbitmap para cargar las imagenes. Ahora tengo otras dudas, para liberar la memoria ¿Hago delete bmp? ¿O hago bmp->Free()? Cuando cargo una imagen usando LoadFromFile ¿Como hago para limpiar esa imagen? Me refiero a que si la imagen la leo con LoadFromFile y luego dubujo encima usando cambas, me quedan restos de la imagen que cargué y necesito limpiar eso para que al usar el cambas esté limpio. Las imagenes son de diferentes tamaños con lo que no me sirve usar un archivo en blanco. El codigo lo tengo que optimizar y mucho ya que ahora que quité todo lo que sobraba hay cosas que no tienen sentido como van.
Responder Con Cita
  #3  
Antiguo 12-12-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola aguml.

Te pongo otra alternativa:
Código PHP:
...

#include<clipbrd.hpp>

// Juntar Bitmaps y copiar a Clipboard
void BitmapsToClipboard(TCheckListBox *clb)
{
  
Graphics::TBitmap *sum = new (Graphics::TBitmap);
  
int wdt 0;

  for(
int i 0clb->Items->Counti++) {
    if (
clb->Checked[i]) {
      
//cargar bmp
      
Graphics::TBitmap *aux = new (Graphics::TBitmap);
      
aux->LoadFromFile(clb->Items->Strings[i] + ".bmp");

      
// ajustar tamaño
      
if(aux->Height sum->Height)
        
sum->Height aux->Height;
      
sum->Width += aux->Width;

      
// dibujar
      
sum->Canvas->Draw(wdt0aux);
      
wdt+= aux->Width;

      
delete aux;
    }
    
Clipboard()->Assign(sum);
  }
  
delete sum;

Llamada ejemplo:
Código PHP:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
  
BitmapsToClipboard(CheckListBox1);

Salida:


Pegado en MsPaint:


En cuanto a tu consulta, en la ayuda de C++ Builder dice:
Cita:
VCL Reference
TObject::Free

TObject See also
____________________________________________________________________________
Destroys an object and frees its associated memory, if necessary.

__fastcall Free();

Description

Do not call the Free method of an object. Instead, use the delete keyword, which invokes Free to destroy an object. Free automatically calls the destructor if the object reference is not NULL.
Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #4  
Antiguo 13-12-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
tu funcion se parece muchisimo a como me quedó a mi pero yo uso otras funciones como lo de copiar una porcion. No sabia que se podia hacer tan sencillo como lo haces tu. Con respecto a lo de usar Free o delete puedo entender que hay que usar delete ¿Es eso? Por cierto, ahora estoy liado con una funcion que hará justo lo contrario, o sea, teniendo un ancho maximo y un alto maximo definidos, divido la imagen en partes de tamaño ancho_maximo*alto_maximo para poder imprimir todas las partes y unir la imagen a modo de mosaico. La idea la tengo mas o menos clara y solo me falta tiempo para intentarlo. Me basaria en un ejemplo de Neftali para delphi.
Responder Con Cita
  #5  
Antiguo 13-12-2014
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: dic 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.508
Poder: 36
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola aguml.
Cita:
Con respecto a lo de usar Free o delete puedo entender que hay que usar delete ¿Es eso?
Usar el método Free para destruir un objeto es una mala práctica. El operador delete garantiza el llamado al destructor y la liberación de la memoria que fué asignada con new, el método Free no garantiza esto último.

Cita:
Por cierto, ahora estoy liado con una funcion que hará justo lo contrario, o sea, teniendo un ancho maximo y un alto maximo definidos, divido la imagen en partes de tamaño ancho_maximo*alto_maximo para poder imprimir todas las partes y unir la imagen a modo de mosaico
Esta parte no sé si la entendí... Supongo que la imágen es mucho mayor al ancho y máximo definidos para poder ser dividida en partes de ancho_maximo*alto_maximo ¿ Es así ?

Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
  #6  
Antiguo 13-12-2014
Avatar de aguml
aguml aguml is offline
Miembro
 
Registrado: may 2013
Posts: 885
Poder: 11
aguml Va por buen camino
bueno, si o no, habrá imagenes que no sean mayor ni en ancho ni en alto, otras que sean mayor solo en una cosa, y otras que sean mayor en ambas. Ademas el ancho y alto maximo varia dependiendo de si eliges el papel A3, A4, o A5 que son los tres tamaños permitidos en mi aplicacion. Ademas mi aplicacion dará a elegir entre redimensionar las imagenes para que quepan en un folio o dividirlas en varios.el esquema lo tengo mas o menos claro. Primero usare una funcion que me devuelva el numero de checkados de la lista y me llene un array de strings con sus rutas. Dentro de dicha funcion se comprueva si la opcion de dividir es la elegida y si es asi se abre cada imagen y se obtiene su tamaño y se comprueba si excede de los maximos. Si excede se llama a la funcion que divide el archivo en partes nos mete las rutas a los nuevos archivos en la lista y si no excede mete la ruta del archivo original. Al final tendriamos un array con todas las rutas a imprimir, otro array con todas las divisiones, un entero que nos indica cuantas rutas hay y otro que nos indica cuantas divisiones. Mas o menos asi lo tengo organizado y me falta crear las funciones.
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Copiar el contenido de un DBGrid en el Portapapeles GerTorresM Varios 6 28-12-2010 18:35:16
Copiar del portapapeles a Word carlos gonzalez Varios 0 12-03-2007 17:16:18
Copiar al portapapeles johurgi Varios 4 22-11-2006 19:47:48
Cómo copiar texto al portapapeles Neftali [Germán.Estévez] Trucos 1 12-09-2006 17:33:18
Copiar del portapapeles a un DBGrid bbjb Varios 1 31-05-2006 18:23:10


La franja horaria es GMT +2. Ahora son las 08:22:42.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi