FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
|
#1
|
|||
|
|||
Guardar y recuperar color pixel originales de una zona pantalla
Buenas...
Estoy intentando guardar una zona de pantalla, modificarla, y despues recuperarla.. para ello guardo en una matriz los colores de cada pixel que forman la zona ha modificar, de la forma Código:
TColor Fondo[10][10]; for( x=pX;x<PFinX,x++) { for (y=pY;y<PFinY,y++) { Fondo[x][y]= Canvas->Pixels[x][y]; } } Código:
for( x=pX;x<PFinX,x++) { for (y=pY;y<PFinY,y++) { Canvas->Pixels[x][y]= Fondo[x][y]; } } Application->ProcessMessages() |
#2
|
||||
|
||||
Hola NEG1414.
Usando un arreglo podes hacer: Código:
... void copiar(TRect R) { for(int x = R.left; x<R.right; x++) for(int y= R.top; y<R.Bottom; y++) Fondo[x][y] = Form1->Canvas->Pixels[x][y]; } void pegar(TRect R, int PX, int PY) { for(int x = R.left; x<R.right; x++) for(int y= R.top; y<R.Bottom; y++) Form1->Canvas->Pixels[PX+x][PY+y] = Fondo[x][y]; } void __fastcall TForm1::Button1Click(TObject *Sender) { Canvas->TextOutA(0,0,"PRUEBA"); // salvar el área de 'PRUEBA' copiar(Rect(0, 0, Canvas->TextWidth("PRUEBA"), Canvas->TextHeight("PRUEBA"))); // escribir algo sobre 'PRUEBA' Canvas->TextOutA(0 0, "XX"); } void __fastcall TForm1::Button2Click(TObject *Sender) { // restaurar el área pegar(Rect(0,0,Canvas->TextWidth("PRUEBA"), Canvas->TextHeight("PRUEBA")), 0, 0); } Header: Código:
class TForm1 : public TForm { __published: TImage *Image1; TLabel *Label1; // sobre la imágen TButton *Button1; TButton *Button2; ... void __fastcall Button1Click(TObject *Sender); private: Graphics::TBitmap *FBM; void __fastcall GetWndArea(int x1, int y1, int x2, int y2); ... Código:
TForm1 *Form1; __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { FBM = new Graphics::TBitmap; randomize(); } void __fastcall TForm1::GetWndArea(int x1, int y1, int x2, int y2) { FBM->Width = x2-x1; FBM->Height= y2-y1; TRect R = Rect(0,0,FBM->Width,FBM->Height); FBM->Canvas->CopyRect(R, Canvas, R); } void Modificar(Graphics::TBitmap *B) { int x,y; for(y=0; y < B->Height; y++) { for(x=0; x < B->Width; x++) B->Canvas->Pixels[x][y] = (TColor)(rand()% 0xFFFFFFF); } } void __fastcall TForm1::Button1Click(TObject *Sender) { // salvar el área de la imagen GetWndArea(0, 0, Image1->Width,Image1->Height); // modificarla Modificar(Image1->Picture->Bitmap); } void __fastcall TForm1::Button2Click(TObject *Sender) { // restaurar el área Canvas->Draw(0, 0, FBM); }
__________________
Daniel Didriksen Guía de estilo - Uso de las etiquetas - La otra guía de estilo .... |
#3
|
|||
|
|||
Gracias por por contestame...
En pricipio tomaria la el primer metodo que has indicado para guardar y mostrar una zona de pantalla.. pero me surge un problema... La captura de "trozo" pantalla y posterior "reposicion" se realiza dentro de un componente visual que he creado de la forma: Código:
class PACKAGE Grafica : public TCustomControl { ........... .......... podria refrescar el componente completamente pero conlleva una serie de operaciones que haria que el refres no fuese fluido y se notara.. para ello prefiero solo "repintar" pixel a pixel la zona donde estaba el panel (que antes habria guardado) de la forma que mostre al inicio del Post... Al aceder al Repintado desde el componente mediante Código:
Form1->Canvas->Pixels[PX+x][PY+y] = Fondo[x][y]; (el segundo metodo al incluir un TImage en la operacion me complica el tema considerablemente..) Puedes indicarme como adaptar el primer metodo a mi caso...Gracias Otra Vez |
#4
|
||||
|
||||
Cita:
Creo que el ejemplo no fué suficientemente claro , no es necesario incluir un TImage para capturar el área del formulario. Tal vez de este modo resulte mas claro: Código:
__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { FBM = new Graphics::TBitmap; } // Guardar área void __fastcall TForm1::GetWndArea(int x1, int y1, int x2, int y2) { FBM->Width = x2-x1; FBM->Height= y2-y1; TRect R = Rect(0,0,FBM->Width,FBM->Height); FBM->Canvas->CopyRect(R, Canvas, R); } // Poner algo en el form, esperarar 1 seg y borrar el área void __fastcall TForm1::Button1Click(TObject *Sender) { char *t1="TEXTO 1",*t2="TEXTO 2"; Canvas->Ellipse(0, 0, 300, 100); Canvas->TextOut(120, 30, t1); Canvas->TextOut(120, 30 + Canvas->TextHeight(t1),t2); Canvas->Brush->Style = bsClear; GetWndArea(0,0,305,105); Sleep(1000); Canvas->Brush->Color = Color; Canvas->Brush->Style = bsSolid; Canvas->FillRect(Rect(0,0,FBM->Width,FBM->Height)); } // restaurar el área borrada void __fastcall TForm1::Button2Click(TObject *Sender) { Canvas->Draw(0, 0, FBM); }
__________________
Daniel Didriksen Guía de estilo - Uso de las etiquetas - La otra guía de estilo .... |
#5
|
|||
|
|||
Muchas gracias por tu tiempo ecfisa voy a probar y te cuento....
|
#6
|
||||
|
||||
Hola NEG1414.
Quien dice 30 dice 31... , yo me refería a implementar algo parecido a esto: Código:
... class PACKAGE MiControl : public TCustomControl { private: Graphics::TBitmap *FArea; TControlCanvas *FCtrlCanvas; //... public: __fastcall MiControl(TComponent *Owner) : TCustomControl(Owner) { FArea = new Graphics::TBitmap; FCtrlCanvas = new TControlCanvas; FCtrlCanvas->Control = this; }; __fastcall ~MiControl() { delete FArea; delete FCtrlCanvas; } void __fastcall LoadArea(void) { FArea->Width = Left + Width; FArea->Height = Top + Height; TRect R = Rect(0, 0, FArea->Width, FArea->Height); FArea->Canvas->CopyRect(R, Canvas, R); }; __property TControlCanvas *Canvas = { read = FCtrlCanvas, write = FCtrlCanvas}; __property Graphics::TBitmap *Area = { read = FArea, write = FArea }; }; MiControl *mc; void __fastcall TForm1::FormCreate(TObject *Sender) { mc = new MiControl(this); } // Crear y mostrar void __fastcall TForm1::btnCreateClick(TObject *Sender) { mc->Left = 0; mc->Top = 0; mc->Width = 250; mc->Height = 300; mc->Parent = this; // Dibujar algo mc->Canvas->Ellipse(0,0,mc->Width-10,mc->Height-40); // Guardar área mc->LoadArea(); } // borrar área void __fastcall TForm1::btnClearClick(TObject *Sender) { mc->Canvas->Brush->Color = Color; mc->Canvas->FillRect(Rect(0,0,mc->Width,mc->Height)); } // Restaurar área void __fastcall TForm1::btnRestoreClick(TObject *Sender) { mc->Canvas->Draw(0,0,mc->Area); } void __fastcall TForm1::FormDestroy(TObject *Sender) { delete mc; }
__________________
Daniel Didriksen Guía de estilo - Uso de las etiquetas - La otra guía de estilo .... |
#7
|
|||
|
|||
Buenas..
Primero daros las gracias y pediros perdon por no haber incluido el componente Prueba.. Acabo de Actualizar el archivo con el componente.. lo podeis descargar de la misma direcion https://app.box.com/s/6gvqol66wahyhuk1negu Gracias o tra vez. Escifa: puedes crear una nueva aplicacion con los mismos archivos descargados y ya no te pedira el componente creapackage lmd70se_B6.bpi ... |
#8
|
||||
|
||||
Hola NEG1414. Pude compilar tu proyecto y he visto que tienes un error al capturar el AreaPanel. El erreo está al definir el TRect fuente y destino. Lo correcto sería así:
Código:
void TPrueba::MostrarPanel() { AreaPanel->Width = 20; AreaPanel->Height = 20; TRect Rs = Rect(PPx, PPy, PPx + AreaPanel->Width, PPy + AreaPanel->Height); TRect Rd = Rect(0,0,AreaPanel->Width,AreaPanel->Height); AreaPanel->Canvas->CopyRect(Rd, Canvas, Rs); //Posicionar y visualizar Panel->Left = PPx; Panel->Top = PPy; Panel->Visible = true; Application->ProcessMessages(); } Pero con esto no resuelves el problema pues al poner invisible tu panel automáticamente se llama al evento paint que redibuja tu control sin saber que había una zona amarilla. Como el evento paint lo dispara WM_PAINT, va a ocurrir despues de que tu redibujes la zona en cuestión y te la machaca. Sólo tienes una forma de evitarlo que es usar un TImage o mejor que tu control de derive de un TImage, en lugar de un TWinControl, En ese caso lo que pintes en el canvas quedará "memorizado" para el evento Paint y evitas efectos indeseables durante el pintado pues no. Tu pintado de rayas iniciales no debe ir en el evento pain sino en funcion a parte que puedes llamar pintafondo y que ejecutas solo al crear el componente. Saludos. |
#9
|
|||
|
|||
Muchas gracias por contestarme scafandra... He entendido perfectamente tu explicacion y me resigno...
|
#10
|
|||
|
|||
Soy un poco cabezon y aun me surge una duda el procedimiento paint(); creo que redibuja siempre en segundo plano( la zona rayada debajo de la zona amarilla) si esto es asi y el proceso es:
Primero zona rayada (Paint() segundo plano) Activo Repintar : zona amarilla (Primer plano) Guardo area Panel (¿¿¿amarilla??) Visualizo Panel (Paint() zona Rayada segundo plano) Oculto Panel(Paint() zona rayada segundo plano) Repinto Arepanel Al repintar el area del panel en teoria amarilla en primer plano por que repinta rayado (o puede se incluso transparente) |
#11
|
||||
|
||||
El problema es que tú no puedes controlar cuando el sistema va a hacer efectivo el Paint puesto que funciona con un mensaje en la cola y se ejecutará cuando le toque, incluso otra APP que se te ponga encima va a provocar el repintado y tu zona amarilla desaparecerá. Esto hace que ocurran efectos aparentemente caprichosos.
Sólo puede funcionar si es la respuesta a WM_PAINT la que te repinta la zona amarilla. Cuando el evento Paint repinta un canvas que tiene guardado, entonces lo hará correctamente, eso es lo que hace un TImage (Tiene un TBitmap que repintará en el canvas). Puedes realizar esto, heredar tu componente de un TImage o que tu componente lo contenga. Las últimas opciones son más sencillas. Saludos. |
|
|
Temas Similares | ||||
Tema | Autor | Foro | Respuestas | Último mensaje |
Dibujar Elipse y Parábola pixel a pixel | Deiv | Gráficos | 9 | 28-11-2016 10:19:41 |
Como obtener el color de un pixel | ilichhernandez | Gráficos | 11 | 02-11-2006 15:40:00 |
Guardar y recuperar | noipa | Varios | 3 | 07-02-2006 14:46:21 |
pasar imagen pixel a pixel | gulder | Gráficos | 7 | 26-06-2005 02:10:45 |
¿ Cual es la mejor forma de implementar una Pizarra con Sockets? pixel a pixel ? | sase | Internet | 1 | 22-10-2003 16:23:50 |
|