2011-09-07 48 views
6

Tengo una rutina procedure DrawStuff(ACanvas: TCanvas; const ARect: TRect) que dibuja algo en un rectángulo específico en un TCanvas. En este momento, llamo al DrawStuff con un lienzo de PaintBox. Ahora estoy agregando una opción Save as, en la que el usuario podrá seleccionar entre una variedad de formatos de archivo (bmp, wmf, jpg, ... - preferiblemente tantos descendientes de TGraphic como sea posible) para guardar los resultados de DrawStuff en .Guardar imagen en una variedad de formatos de archivo

Al llamar a TMetafile y guardar eso como "bla.bmp" o Assign al TPicture no funciona correctamente, p. Ej. produce archivos con extensión ".bmp" que no son bitmaps. Ahora mismo no puedo imaginar una solución que no implique especial carcasa todos los formatos de archivo único:

  • bmp - Uso TBitmap.Canvas.
  • wmf/fem: Use TMetafileCanvas.
  • , etc, etc

¿Sabes tiene alguna idea para mí?

+2

Es muy fácil hacer una rutina "uniforme" para guardar BMP, PNG, GIF, JPG, etc., pero es mucho más difícil si también incluye WMF o EMF, ya que estos últimos son * formatos de imagen vectorial *, mientras que los primeros son * formatos de imagen * raster *. A menos que, por supuesto, elija guardar la imagen como un mapa de bits ráster incrustado en su EMF/WMF, pero en tal caso es completamente estúpido usar el formato EMF/WMF ... –

+0

wmf/fem de envoltura especial estaría bien. ¿Puedes darme consejos sobre la rutina de uniformes que mencionas? –

+0

PD: Pensé en dibujar un metarchivo y luego 'Asignar' a un 'TPicture' podría funcionar, ya que parece ser algo así como un conjunto de llamadas GDI grabadas. –

Respuesta

9

supongo una conversión "tonto" probablemente tan simple como esto:

type 
    TGraphicTypeEnum = (gteBMP, gteJPG, gteTIF, gtePNG); 

procedure SaveGraphicAs(AGraphic : TGraphic; AGraphicType : TGraphicTypeEnum; AFileName : String); 
var vGraphicClass : TGraphicClass; 
    vTargetGraphic : TGraphic; 
    vBmp : TBitmap; 
begin 

    case AGraphicType of 
    gteBMP : vGraphicClass := TBitmap; 
    gtejpg : vGraphicClass := TJPEGImage; 
    gtetif : vGraphicClass := TWICImage; 
    gtepng : vGraphicClass := TPngImage; 
    else 
    // EXIT; or raise... 
    end; 
    if aGraphic is vGraphicClass then //As suggested by Rob Kennedy 
    AGraphic.SaveToFile(AFileName) 
    else 
    begin 
    vBmp := nil; 
    vTargetGraphic := vGraphicClass.Create; 
    try 
     vBmp := TBitmap.Create; 
     vBmp.Assign(AGraphic); 
     vTargetGraphic.Assign(vBmp); 
     vTargetGraphic.SaveToFile(aFileName); 
    finally 
     vTargetGraphic.Free; 
     vBmp.Free; 
    end; 
    end; 
end; 

Asignación a un TPicture no funcionó, ya que cuando se asigna a un TPicture, TPicture convertirá el gráfico para la clase estás asignando desde.

Tenga en cuenta que en mi ejemplo, hay 2 capas de conversión, ya que la imagen original se convierte en mapa de bits antes de convertirse al formato final. Puede haber bastante pérdida de información en el proceso. La mayoría (¿todos?) Del tipo de gráfico saben cómo convertir a TBitmap y desde este, pero TJPEGImage no tiene idea de cómo convertir a TPngImage y viceversa.

Se puede desarrollar un método de conversión más eficiente que mantenga la transparencia y otros efectos específicos de un formato de archivo, pero eso es lo que yo sé. Pero dependiendo de tus necesidades, eso podría ser suficiente.

+0

Probablemente valga la pena comprobar 'si AGraphic es vGraphicClass' y omitir la conversión de mapa de bits si es verdadera. De lo contrario, perderá calidad de imagen incluso cuando guarde un archivo JPEG como JPEG. –

+0

O omita llamar a la función SaveGraphicAs y simplemente llame a AGraphic.SaveToFile. Hay muchos otros problemas que podrían surgir. Un tercero podría registrar su propia clase PNG (DevExpress lo hace). Entonces terminarías con 'TdxPNGImage es TPNGImage' (que sería falso). Por desgracia, no es posible en este momento obtener la clase actualmente registrada para una extensión determinada (QC57402 solicitada el 2008-01-24 ... Todavía abierta). Probablemente sea más fácil para la persona que llama averiguar si el gráfico ya está en el formato correcto. Pero sí, supongo que no estaría de más hacer esa optimización. –

Cuestiones relacionadas