FTP | CCD | Buscar | Trucos | Trabajo | Foros |
|
Registrarse | FAQ | Miembros | Calendario | Guía de estilo | Temas de Hoy |
|
Herramientas | Buscar en Tema | Desplegado |
#1
|
|||
|
|||
Vaciar un Timage
Hola a tod2@s,
tengo un ligero problema, que quizas sea un tonteria (seguro) pero no doy con la solucion. Tengo un Timage, y cargo una imagen al mismo, sin problemas, los estrecho y se ajusta perfecto. Pero ahora viene mi problema, ¿como borro del Timage, la imagen que he cargao y lo dejo vacio, como si no hubiese cargao antes otra imagen? Gracias |
#2
|
||||
|
||||
Durante el diseño: Abres el cuadro de edición de la propiedad Picture y oprimes el botón "Clear"
Durante la ejecución: Image1.Picture := nil; // Saludos |
#3
|
|||
|
|||
Que velocidad, muchisimas gracias.
|
#4
|
|||
|
|||
Cita:
Tal vez sea mejor: Image1.Picture.Free; Image1.Picture := nil; o abreviado Image1.Picture.FreeNil; Ojo que si existe otra referencia al mismo objeto, que podría ser usada después, es necesario colocarla en "nil" antes de destruir el objeto u ocurrirá un error ya que esa otra referencia seguirá apuntando a la posición donde estaba el objeto referenciado por Picture. Saludos. |
#5
|
||||
|
||||
No te olvides que Picture es una propiedad de la clase TImage. Si te das el tiempo de revisar el código de la VCL te darás cuenta que en el método de asignación de la propiedad (SetPicture) cuando se recibe una referencia a nil, la memoria reservada por la imagen actual en efecto se libera.
Trataré de explicarte la forma en que trabaja la VCL en este sentido. Las propiedades (un excelente invento de borland, creo yo) son una forma fantástica de introducir efectos secundarios de este tipo que al final ahorran trabajo y líneas de código. Cuando vos haces una asignación, en realidad ocurre tras bambalinas una serie de acciones que logran que esa acción sea efectiva. Por ejemplo, cuando asignas un valor al Caption de un TLabel, no solo se cambia el valor de este, sino se inválida el área que ocupa en pantalla, de manera que si está visible, el cambio se vea reflejado al usuario. Si no fuera así, siempre tendrias que llamar a Invalidate después de hacer un cambio para que este se reflejara. En ocasiones, estas propiedades son objetos, y es muy importante comprender los efectos de invocar directamente los métodos de estos objetos, sobre todo los constructores y destructores, pues es muy probable que provoquemos un fallo en nuestro programa (como podras comprobar si compilas la recomendación que das, seguramente provocará un AccessViolation). De hecho, nunca he visto una propiedad de un objeto de la VCL que requiera que su constructor/destructor sea invocado directamente, con componentes de terceros... mejor revisar la documentación, y el código si está disponible. Algo similar ocurre con la asignación de valores a estas propiedades, por ejemplo cuando querés asignar una imágen contenida en una variable (digamos una instancia de TBitmap) a un TImage, basta con hacer Image1.Picture := MyBMP; Si la VCL no estubiera preparada para manejar esto, en realidad harias que la propiedad Picture apunte a la misma dirección donde apunta MyBMP, y al liberar este, dejarías al TImage apuntando a una dirección donde en realidad ya no existe un objeto, lo cual a la postre seguramente provocaría un AccessViolation. Nuevamente si te das una vuelta por las unidades de la VCL verás que en realidad se hace una copia de la imágen (mediante assign), manteniendo de esa forma por un lado la independencia de las propiedades de la VCL con respecto de tus propias variables locales (o globales), y por el otro la responsabilidad de cada uno de liberar la memoria y/o recursos consumidos, la VCL su propia memoria, y vos la de tus variables, (llamando a MyBMP.Free cuando ya no lo necesites mas). Espero haber sido claro y no confundirte con todo este rollo... Hasta luego.
__________________
Juan Antonio Castillo Hernández (jachguate) Guía de Estilo | Etiqueta CODE | Búsca antes de preguntar | blog de jachguate Última edición por jachguate fecha: 02-02-2004 a las 04:42:30. Razón: Corregir alguna redundancia (no prometo corregirla toda... ;) ) |
#6
|
|||
|
|||
Sip, tienes razón, tome a "picture" textualmente como referencia a objeto y no como propiedad. Y si se llamaría a "free" directamente, el componente no tendría forma de "enterarse" de que el objeto que apunta su referencia interna ya fue destruido y efectivamente ocasionaría un error.
Última edición por Amilius fecha: 12-02-2004 a las 18:39:27. |
#7
|
|||
|
|||
Borrar un TImage
He estado leyendo el foro, el cual me saco de unas dudas que tenia, lo cual les agradezco mucho. Les dejo un fragmento de codigo que elabore, se trata de cargar un TImage con un openDialog, filtrando obviamente solo las imagenes y obteniendo despues el tamaño de la imagen seleccionada, si el tamaño sobrepasa 500kb (aprox) manda un mensaje de error, limpia el TImage y cierra los archivos (que se abren para obtener el tamaño de la imagen).
Espero este aporte sirva para alguien Saludos!!! //codigo del boton donde ejecuto el openDialog para buscar la imagen procedure TfrmSubir_imagenes.btnArchivoClick(Sender: TObject); var narch:String; tam: LongWord; arch2: Thandle; arch: file; begin try if(open1.Execute)then //ejecuta el open dialog begin narch := open1.FileName; //obtiene el nombre de la imagen txtArchivo.Text := narch; //carga un TEdit con el nombre del archivo //reset(arch); imagen1.Picture.LoadFromFile(narch); //carga el Timage con la imagen seleccionada AssignFile(arch, narch); //crea un archivo con el nombre de la imagen reset(arch);//reinicializa el archivo recien creado para su manejo if(FileSize(arch) > 3799)then //valida el tamaño que sea menor de 500kb (aprox) begin MessageDlg('La imagen es demasiado grande, debe ser menor a 450kb y en '+#13+#10+'formato jpg'+#13+#10+'Seleccione otra imagen o edite la imagen deseada', mtError, [mbOK], 0); //mensaje de error //imagen1.Picture.Free; imagen1.Picture := nil; //LIMPIA EL TImage self.Repaint; //refresca la forma txtArchivo.Clear; //limpia el campo de texto CloseFile(arch); //cierra el archivo (necesario para que no mande errores al querer abrir otra vez el mismo archivo exit; //sale del procedimiento end; CloseFile(arch); //cierra el archivo imagen1.Hint := narch; //asigna al hint del TImage la ruta de la imagen cargada self.Repaint; //refresca la forma end else begin MessageDlg('Debe seleccionar un archivo para subir', mterror, [mbOk], 0); end; except on e:Exception do begin MessageDlg('Error al buscar el archivo de la imagen debido a:'+#10+e.Message, mtError, [mbOk], 0); exit; end; end; end; |
|
|
|