Club Builder - Foros de discusión Club Builder
Foro de C++Builder en español
 
 FAQFAQ   BuscarBuscar   MiembrosMiembros   Grupos de UsuariosGrupos de Usuarios   RegistrarseRegistrarse 
 PerfilPerfil   Entra para ver tus mensajes privadosEntra para ver tus mensajes privados   EntrarEntrar 

Se puede hacer algo para alcelerar este código?

 
Publicar nuevo tema   Responder al tema    Foros de discusión -> Consultas
Ver tema anterior :: Ver tema siguiente  
Autor Mensaje
Mensaje    Asunto: Se puede hacer algo para alcelerar este código? Responder citando

Hola de nuevo:

Estoy tratando de hacer zoom de una imagen.
Con el codigo que tengo funciona bién y rápido con imagenes pequeñas, pero para imagenes grandes la cosa cambia y tarda un poco, no es que tarde ni un segundo pero no es instantaneo como con imagenes pequeñas.

Sabe alguien como puedo hacer que esto vaya un poquito mas rápido?

Aqui esta el código que tengo:
Lo que hago es que tengo una imagen guardada en FondoAux y cada vez que quiero hacer zoom pues la copio en Fondo:
Código:

  TRect Dest;
  TRect Scr;
  Dest = Rect(0,0, Fondo->Width , Fondo->Height);
  Scr = Rect(0,0, FondoAux->Picture->Bitmap->Width , FondoAux->Picture->Bitmap->Height);
  SetStretchBltMode(Fondo->Canvas->Handle, HALFTONE);
  Fondo->Canvas->CopyRect(Dest, FondoAux->Canvas, Scr);
  Fondo->Repaint();


Muchas gracias!
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Hola otra vez:

he estado probando con esto y tampoco:
Código:

SetStretchBltMode(Fondo->Canvas->Handle, HALFTONE);
  StretchBlt(Fondo->Picture->Bitmap->Canvas->Handle,0,0,Fondo->Picture->Bitmap->Width,Fondo->Picture->Bitmap->Height,
             FondoAux->Picture->Bitmap->Canvas->Handle,0,0,FondoAux->Picture->Bitmap->Width,FondoAux->Picture->Bitmap->Height,SRCCOPY);


He descubierto que donde se queda "pensando" (durante unos 500 ms, estoy trabajando con una imagen bmp de 24Mb) es solo en la funcion CopyRect y en la funcion StretchBlt, que son las responsables de hacer el trabajo.

Bueno, no desisto y si alguien sabe como hacer el proceso más rápido o puede aportar alguna idea...

Muchas gracias.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Quizás la solución sea manejar una "Ventana" de la imagen mas pequeña.
Si la imagen es muy pesada y la ventana de visualización donde la ves, es mas pequeña, y tiene un zoom negativo para abarcar toda la imagen... Un zoom positivo no tiene porque ser de toda ella, sino solo la parte de imagen que se necesite para que el tamaño final corresponda, al agrandarla, al de la ventana de visualización....

No se si lo que ya haces es esto que te propongo. En fin, es una idea...

Saludos.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Hola escafandra,

habia pensado en algo parecido, no debe ser muy dificil hacer algo asi.
Te agradezco la respuesta.

Un saludo.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

No he probado nada, pero no en principio no lo veo difícil, sólo tienes que jugar con el TRect fuente y destino. Si quieres duplicar el tamaño, el rect final será el doble que el inicial....

Saludos.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Hola de nuevo:

he estado investigando un poco sobre el zoom, el problema es que tengo un TImage dentro de un TScrollBox y si hago zoom por zonas como suguiere escafandra, el problema viene cuando nuevo las barras de scroll, al moverlas las demas zonas de la imagen no tienen zoom.

Un saludo!
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Entonces haz el zoom en la zona mayor, contando con lo no visto.
Supongo que la ventana de visualización, aun con ScrollBar, será menor que el tamaño real de esa imagen tan pesada.

Otra posibilidad es reacer el zomm de la zona "añadida" al mover el el ScrollBar. Puede enlentecer el movimiento, pero bien es verdad que lo añadido será una zona pequeña a cada movimiento de la barra del ScrollBar.

Saludos.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Aunque si lo pienso mejor, puedes actualizar el zoom a la ventana visible como has hecho, y en otro hilo terminar de hacer el zoom a toda la imagen.

Mientras el hilo secundario no ha terminado el zoom, puedes hacer zoom parcial de la zona nueva que se visualiza con el ScroolBar.

De esa manera no se nota tanto y las tardanzas que se puedan producir con el ScrollBar (si se mueve muy deprisa) desaparecerán en cuanto el hilo secundario tenga lista la nueva imagen con zoom.

Es laborioso pero creo que será efectivo. Cuéntanos.

Saludos.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Hola!

He estado mirando la funcion StretchBlt() , pero nada, tampoco acelera los suficiente como para notarlo.
Mira, aunque me llevo bién con los Threads, y es buena idea, creo que debe haber algún método más rapido.
Por ejemplo algo asi como bloquear todos los eventos de pintado y pintar en memoria, y después hacer una copia al canvas. He estado mirando las funciones

He encontrado algo que me puede dar pistas...
Cita:
Hi, there.

I think the CopyRect-Function works alot faster.
I use this function e.g. for loupe-ing a certain
part of any bitmap/the desktop, etc.
I found it works really fast.

If that's not enough:

Try to access the memory directly. (Not a
very clean style and maybe forbidden
with WinNT, I don't know...)

-> void* Pointer1 = SourceBmp->Canvas;
-> void* Pointer2 = DestBmp->Canvas;

In this case I don't know, which routines
are faster:

The whole Mem-Funcions of Windows, like CopyMem, ZeroMemory, etc.
or the standard-library functions, like memcpy, memset, etc...
try.
The Names of the Win-functions can differ, sorry


y otra...
Cita:
draw your image in an off-screen TBitmap using direct access
to its Scanline[]


Muchas gracias, cuando sepa algo (espero que sea pronto os lo diré)
Saludos!
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Bueno, si vas a ir directamente al mapa de memoria, entonces esto puede que te interese.

Windows trata las imágenes como objetos DIB que son la imagen en memoria de los bmp (de distinta profundidad de color). Las API que usan obgetos DIB trabajan con estas imágenes de memoria.

Hace unos años cree un código para acceder directamente a los pixels de forma rápida, y lo conseguí.

Para convertir un objeto TBitmap a este tipo de objeto analiza este código:

Código:

Código:
BITMAPFILEHEADER *FileHeader;
BITMAPINFO       *Info;
void             *Bits;
TMemoryStream    *SMBitmap;
 
SMBitmap = new TMemoryStream;
Bitmap->SaveToStream(SMBitmap);
SMBitmap->Position = 0;
 
FileHeader = (LPBITMAPFILEHEADER)SMBitmap->Memory;
Info = (LPBITMAPINFO)((Byte*)SMBitmap->Memory + sizeof(BITMAPFILEHEADER));
int  nColors = Info->bmiHeader.biClrUsed;
int  colorAlloc = nColors * sizeof(RGBQUAD); // size of color tables

// Info es la imagen del DIB  (BITMAPINFO)
// Esta es la imagen en memoria de los pixels:
Bits = (char*)Info + ((int)Info->bmiHeader.biSize + colorAlloc);


Con esto lo que consigues es acceder directamente a la memoria de la imagen, no te resuelve el tema, pero puedes seguir investigando.

Saludos.
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

Hola de nuevo:
gracias por tu respuesta escafandra, si soy sincera te diré que viendo el código no por donde empezar, y menos aún para hacer el zoom, creo que va a ser más complejo de lo que pensaba.

He estado mirando por los grupos de google, y con lo visto, he creado este código, funciona, pero vamos que no acelera casi nada.
Código:
Graphics::TBitmap* F = new Graphics::TBitmap;
    Graphics::TBitmap* Fa = new Graphics::TBitmap;

    F=Fondo->Picture->Bitmap;
    Fa=FondoAux->Picture->Bitmap;

    char *Buffer = NULL;
    unsigned int HeaderSize = 0, ImageSize = 0;
    GetDIBSizes( Fa->Handle, HeaderSize, ImageSize );
    Buffer = new char[ HeaderSize + ImageSize ];
    BITMAPINFO *pBmi = (BITMAPINFO*) Buffer;
    unsigned char *pImage = (unsigned char*) Buffer + HeaderSize;
    GetDIB(Fa->Handle, FondoAux->Picture->Bitmap->Palette, pBmi, pImage);
    StretchDIBits( F->Canvas->Handle, 0, 0, F->Width, F->Height, 0, 0, Fa->Width, Fa->Height, pImage, pBmi, DIB_RGB_COLORS, SRCCOPY );
    delete [] Buffer;


Muchas gracias
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mensaje    Asunto: Responder citando

estaba mirando este hilo..... dejo aqui este codigo

Código:

Graphics::TBitmap *Temp = new Graphics::TBitmap;
   Temp->Width = 1260;
   Temp->Height = 960;
   TRect DestRect = Rect(0,0,Temp->Width, Temp->Height);
   Temp->Canvas->StretchDraw(DestRect, Image1->Picture->Bitmap);
   Temp->SaveToFile("hierbb.bmp");
   ShowMessage("Resized and Saved!!");
Volver arriba
Ver perfil de usuario Enviar mensaje privado
Mostrar mensajes de anteriores:   
Cambiar a:  
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


Hosting WordPress Indedmedia desde 3,99 €
© 2002–2026 Club Builder · Funciona con phpBB.