2010-07-17 21 views
5

Sto tentando di rimuovere tutti i pixel bianchi o trasparenti da un'immagine, lasciando l'immagine reale (ritagliata). Ho provato alcune soluzioni, ma nessuna sembra funzionare. Qualche suggerimento o ho intenzione di passare la notte a scrivere il codice di ritaglio delle immagini?C# - Ritaglia trasparente/Spazio bianco

+0

quindi ci sono altre persone che sognano di continuamente a scrivere la stessa riga di codice più e più volte? Pensavo di essere l'unico :-) –

+1

sarebbe di aiuto alla comunità se si dettaglio almeno uno dei tuoi approcci e ha spiegato come non ha funzionato. –

risposta

3
public Bitmap CropBitmap(Bitmap original) 
{ 
    // determine new left 
    int newLeft = -1; 
    for (int x = 0; x < original.Width; x++) 
    { 
     for (int y = 0; y < original.Height; y++) 
     { 
      Color color = original.GetPixel(x, y); 
      if ((color.R != 255) || (color.G != 255) || (color.B != 255) || 
       (color.A != 0)) 
      { 
       // this pixel is either not white or not fully transparent 
       newLeft = x; 
       break; 
      } 
     } 
     if (newLeft != -1) 
     { 
      break; 
     } 

     // repeat logic for new right, top and bottom 

    } 

    Bitmap ret = new Bitmap(newRight - newLeft, newTop - newBottom); 
    using (Graphics g = Graphics.FromImage(ret) 
    { 
     // copy from the original onto the new, using the new coordinates as 
     // source coordinates for the original 
     g.DrawImage(...); 
    } 

    return ret 
} 

Si noti che questa funzione sarà lenta come sporco. GetPixel() è incredibilmente lento e anche l'accesso alle proprietà Width e Height di un Bitmap all'interno di un ciclo è lento. LockBits sarebbe il modo corretto per farlo: ci sono un sacco di esempi qui su StackOverflow.

+1

Grazie, mi sono trovato a metà strada lì. L'unico problema è, voglio anche ridimensionare l'immagine se è più grande di una dimensione specificata. C'è più codice di quello che si adatta alla casella dei commenti, ma l'immagine originale occupa solo metà dell'immagine finale. Il codice è http://pastebin.com/He3S8aCH – Echilon

+0

Ho trasposto due variabili: P. Risolto il problema, aspettatevi presto un post sul blog (vi collegherò qui). – Echilon

+0

Penso di aver sbagliato anche io. I bit che dicono 'color.R! = 0' ecc. Dovrebbero effettivamente dire' color.R! = 255', poiché un pixel bianco avrà valori R, G e B di 255 per ciascuno (un RGB di 0,0, 0 è nero). Se la versione originale ha funzionato per te, probabilmente ha ritagliato solo i pixel trasparenti (e quelli neri). – MusiGenesis

2

Il controllo per pixel dovrebbe fare il trucco. Scansione di ogni riga per trovare la linea vuota dall'alto & in basso, scansionare ogni riga per trovare i vincoli di destra a sinistra & (questo può essere fatto in un passaggio con righe o colonne). Quando viene trovato il vincolo, copia la parte dell'immagine su un altro buffer.

9

Quindi, quello che vuoi fare è trovare il pixel in alto a sinistra più bianco/trasparente e in basso a destra il pixel non bianco/trasparente. Queste due coordinate ti daranno un rettangolo che potrai estrarre.

// Load the bitmap 
    Bitmap originalBitmap = Bitmap.FromFile("d:\\temp\\test.bmp") as Bitmap; 

    // Find the min/max non-white/transparent pixels 
    Point min = new Point(int.MaxValue, int.MaxValue); 
    Point max = new Point(int.MinValue, int.MinValue); 

    for (int x = 0; x < originalBitmap.Width; ++x) 
    { 
    for (int y = 0; y < originalBitmap.Height; ++y) 
    { 
     Color pixelColor = originalBitmap.GetPixel(x, y); 
     if (!(pixelColor.R == 255 && pixelColor.G == 255 && pixelColor.B == 255) 
     || pixelColor.A < 255) 
     { 
     if (x < min.X) min.X = x; 
     if (y < min.Y) min.Y = y; 

     if (x > max.X) max.X = x; 
     if (y > max.Y) max.Y = y; 
     } 
    } 
    } 

    // Create a new bitmap from the crop rectangle 
    Rectangle cropRectangle = new Rectangle(min.X, min.Y, max.X - min.X, max.Y - min.Y); 
    Bitmap newBitmap = new Bitmap(cropRectangle.Width, cropRectangle.Height); 
    using (Graphics g = Graphics.FromImage(newBitmap)) 
    { 
    g.DrawImage(originalBitmap, 0, 0, cropRectangle, GraphicsUnit.Pixel); 
    } 
+0

Ottima soluzione! Ho rimosso '|| pixelColor.A <255' per farlo funzionare. – krlzlx

0

Ho trovato un metodo per eseguire il batch di alcune migliaia di file .jpg in circa 10 minuti, ma non l'ho fatto nel codice. Ho usato la funzionalità Converti di Snag-It Editor. Non so se questa sia un'opzione per te, se hai bisogno di eseguire questa operazione una volta o se il tuo bisogno è in corso, ma per il prezzo del software, che non è molto, ho considerato questa soluzione decente. (io non lavorano o che rappresentano Techsmith.)

Joey

Problemi correlati