2012-12-28 12 views
7

Se si considera l'immagine seguente, è un'icona abbastanza semplice, con dimensioni 32x32. Intorno all'icona c'è un rettangolo trasparente, anche se ho riempito i quattro angoli con un colore uniforme durante il test.Perché Graphics.DrawImage ritaglia parte della mia immagine?

Source Image

Ora consideriamo questo codice, che trae semplicemente l'immagine, ma su scala più ampia:

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 

    e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor; 
    e.Graphics.DrawImage(Properties.Resources.icon_32a, new RectangleF(0, 0, 512, 512), new RectangleF(0, 0, 32, 32), GraphicsUnit.Pixel); 
} 

Si noti che sto disegnando l'immagine completa e non sto cercando di raccolto in alcun modo, basta ingrandirlo.

Infine, questo è l'uscita il test mi dà:

Painted example

notare il problema? La metà dei pixel nella riga superiore e nella colonna sinistra sono scomparsi. Se poi provo a sovrapporre una griglia a questo, sembra piuttosto orribile dato che la griglia è allineata correttamente, ma l'immagine non lo è. Anche raddoppiando la dimensione a 64, 64 introduce questo primo ritaglio di riga/colonna.

Nota, ho anche provato a spostare il rettangolo di destinazione nel caso in cui fosse stato disegnato prima di 0,0, ma non era così.

Ho anche provato a utilizzare diverse modalità di interpolazione, ma per quanto ho potuto vedere attraverso il mal di testa che induce sfocatura, i pixel erano ancora ritagliati, quindi non credo sia dovuto alla modalità di interpolazione.

Ho anche provato a utilizzare diverse modalità grafiche, ma a parte il fatto che non sembra essere di aiuto, devo comunque incollare i pixel.

Ho provato di nuovo con una nuova copia dell'immagine a 96 dpi per curiosità e ho ottenuto lo stesso effetto, quindi non penso che sia la risoluzione delle immagini di origine.

L'innesto su cannucce e l'utilizzo di Rectangle invece di RectangleF non hanno avuto alcun effetto.

Qualcuno può offrire qualche indizio sul perché questo apparente raccolto si sta verificando?

Grazie;

risposta

7

Il PixelOffsetMode è impostato per default PixelOffsetMode.Half:

Specifica che i pixel sono compensate da -.5 unità, sia orizzontalmente che verticalmente , per antialiasing alta velocità.

Nel tuo caso, un pixel nell'immagine originale è di 8 pixel nell'immagine risultante, che è esattamente quello che ti manca.

impostandolo a PixelOffsetMode.None Prova:

protected override void OnPaint(PaintEventArgs e) 
{ 
    base.OnPaint(e); 

    e.Graphics.PixelOffsetMode = PixelOffsetMode.None; 
    e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor; 
    e.Graphics.DrawImage(Properties.Resources.icon_32a, new RectangleF(0, 0, 512, 512), new RectangleF(0, 0, 32, 32), GraphicsUnit.Pixel); 
} 
+6

Rotem, grazie per la risposta - io non era a conoscenza di questa particolare proprietà. L'ho provato ma non funzionava ancora. Tuttavia, ho trovato se l'ho impostato 'HighQuality', quindi la mia immagine è stata renderizzata correttamente. Mi sembra uno stupido valore predefinito, ma facile da correggere se lo sai - grazie ancora! –

+0

Ho avuto lo stesso problema. Inoltre non era a conoscenza della proprietà 'PixelOffsetMode'. Ancora una volta, 'PixelOffsetMode.None' non ha funzionato per me nonostante fosse l'impostazione ovvia ma' PixelOffsetMode.HighQuality' ha funzionato. –

1

Basta che copre risposta comfirmed dagli utenti, ho provato io stesso e il problema è stato risolto con PixelOffsetMode.HighQuality invece none.

C#

e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; 

mio caso C++ gestito:

e->graphics->PixelOffsetMode = System::Drawing::Drawing2D::PixelOffsetMode::HighQuality;