2009-02-19 34 views
7

Estoy tratando de dibujar imágenes en un formulario C# (en PictureBoxes, así como usando Graphics.DrawImage()), y estoy buscando una forma de dibujarlas smooth. Las imágenes deben ser un formato que admita transparencia, por lo tanto, PNG, GIF, SVG y WMF. C# no es compatible con archivos SVG listos para usar, y no he encontrado una buena biblioteca de terceros para usar (encontré SvgNet, pero no pude encontrarlo).Cómo dibujar imágenes suaves con C#?

Necesito dibujar un archivo WMF, que C# puede hacer a través de la función Image.FromFile(), pero no es anti-alias. Me preguntaba si hay alguna manera de suavizar esto?

Respuesta

7

Al dibujar la imagen en un lienzo, se puede cambiar el modo de interpolación a algo más agradable que el vecino más cercano para hacer imágenes redimensionadas suaves:

Graphics g = ... 
g.InterpolationMode = InterpolationMode.HighQualityBicubic; 
g.DrawImage(...); 

Usted tendrá que añadir para conseguir System.Drawing.Drawing2D la interpolationMode enum.

El uso de PictureBox será un problema, ya que no expone una propiedad InterpolationMode, por lo que tendrá que rodar la suya o descargar una.

+0

alguna idea de dónde podría encontrar una descargable, o cómo ir haciendo mi propia? Soy un desarrollador de C# novato, y escribir el mío puede ser una tarea que está un poco más allá de mis capacidades actuales. –

+0

Como novato, la forma más fácil de comenzar a rodar su propia clase es colocar un control Panel y luego escribir su evento Paint (en la ventana de propiedades, seleccionar eventos [icono del rayo] luego hacer doble clic al lado del evento Paint en la lista) Use el parámetro e.Graphics para escribir el código de extracción de reemplazo. – David

+0

Great Great Great ,,, millones de gracias – bebosh

15

Las respuestas anteriores, aunque bien intencionadas, solo fueron parcialmente correctas.

¿Qué era correcto? PictureBox no expone InterpolationMode.

¿Qué fue la base?

1) Si bien puede establecer fácilmente esa propiedad en el evento Paint desde el cuadro de imagen, en su elemento principal, o mediante una sustitución en una clase derivada. . . De cualquier manera funciona y ambos son igual de fáciles. Sin embargo, a menos que se establezca SmoothingMode, se ignorará InterpolationMode. No obtendrá ningún suavizado sin SmoothingMode configurado en SmoothingMode.AnitAlias.

2) Usar un Panel cuando ha expresado claramente su interés en utilizar las funciones de PictureBox es la dirección incorrecta a seguir. No tendrá la capacidad de cargar, guardar o asignar imágenes directamente sin codificar explícitamente esas propiedades. . . ¿Por qué reinventar la rueda? Al obtener PictureBox, obtienes todo eso gratis.

Las noticias son aún mejores ya que he hecho el trabajo duro y tardé menos que escribir este mensaje.

He proporcionado dos versiones que se derivan de PictureBox. First es un ejemplo simple que siempre utiliza la mejor representación de calidad posible. Esta es también la representación más lenta. Second es una clase que permite a cualquier persona establecer los diversos parámetros de representación mediante propiedades fuera de la clase derivada. Una vez establecidos, estos se utilizan en la anulación de OnPaint.

public class HighQualitySmoothPictureBox : PictureBox 
{ 
    protected override void OnPaint(PaintEventArgs pe) 
    { 
     // This is the only line needed for anti-aliasing to be turned on. 
     pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; 

     // the next two lines of code (not comments) are needed to get the highest 
     // possible quiality of anti-aliasing. Remove them if you want the image to render faster. 
     pe.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 
     pe.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
     // this line is needed for .net to draw the contents. 
     base.OnPaint(pe); 
    } 
} 

...

public class ConfigurableQualityPictureBox : PictureBox 
{ 
    // Note: the use of the "?" indicates the value type is "nullable." 
    // If the property is unset, it doesn't have a value, and therefore isn't 
    // used when the OnPaint method executes. 
    System.Drawing.Drawing2D.SmoothingMode? smoothingMode; 
    System.Drawing.Drawing2D.CompositingQuality? compositingQuality; 
    System.Drawing.Drawing2D.InterpolationMode? interpolationMode; 

    public System.Drawing.Drawing2D.SmoothingMode? SmoothingMode 
    { 
     get { return smoothingMode; } 
     set { smoothingMode = value; } 
    } 

    public System.Drawing.Drawing2D.CompositingQuality? CompositingQuality 
    { 
     get { return compositingQuality; } 
     set { compositingQuality = value; } 
    } 

    public System.Drawing.Drawing2D.InterpolationMode? InterpolationMode 
    { 
     get { return interpolationMode; } 
     set { interpolationMode = value; } 
    } 

    protected override void OnPaint(PaintEventArgs pe) 
    { 
     if (smoothingMode.HasValue) 
      pe.Graphics.SmoothingMode = smoothingMode.Value; 
     if (compositingQuality.HasValue) 
      pe.Graphics.CompositingQuality = compositingQuality.Value; 
     if (interpolationMode.HasValue) 
      pe.Graphics.InterpolationMode = interpolationMode.Value; 

     // this line is needed for .net to draw the contents. 
     base.OnPaint(pe); 
    } 
} 
+0

Una muy buena respuesta. Lo único que agregaría son algunos atributos como Browsable, ToolboxItem, Description y Category para poder usar este control en VisualDesigner. – 0xBADF00D

+2

@hichaeretaqua Gracias por sus amables palabras. Estoy de acuerdo en que una implementación final necesitará esos atributos. Sin embargo, encuentro que los elementos que no están directamente relacionados con la respuesta son desordenados y pueden distraer al alumno del mensaje deseado. Es por eso que no los proporcioné. –

Cuestiones relacionadas