2016-04-20 11 views
0
geändert.

Ich spiele mit dem Austauschen von Farbwerten eines Bildes, aber ich habe etwas gefunden, das ich nicht ganz verstehe - und ich kann kein gutes finden Lesen Sie weiter auf Google in der Sache. Ich kann die Farben eines Bildes vertauschen, aber es verändert auch die Größe der Ausgabedatei im Vergleich zur Größe der Eingabedatei.Dateigröße wird nach dem Austauschen von Farbwerten in Bitmap

Nachfolgend finden Sie eine Testklasse die ich geschrieben habe, die Angelegenheit zu prüfen, und was es tut, um es zusammenzufassen ist:

  1. die Bitmap-Speicher zuweisen.
  2. Erstellen Sie ein Array von RGB-Werten.
  3. Teilen Sie das RGB-Array in drei separate Arrays auf (r, g und b).
  4. Swap alle Werte in rot (r [0] < -> r [1], r [2] < -> r [3], etc.)
  5. die drei Arrays bei und an die Anordnung von RGB-Werte zuweisen .
  6. In Bitmap zurückkopieren.
  7. Geben Sie den zugewiesenen Speicher frei.
  8. Exportieren Sie die Datei.

-Code ist wie unten zu sehen:

using System; 
using System.Drawing; 
using System.Drawing.Imaging; 
using System.Runtime.InteropServices; 

namespace GraphTheory 
{ 
    class Test 
    { 
     public Test(Bitmap bmp) 
     { 

      #region Assign bitmap to memory 

      // Rectangle to hold the bmp. 
      Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height); 

      // Lock the bitmap to the rectangle/system memory. 
      BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadWrite, bmp.PixelFormat); 

      // Get the adress of the first line. 
      IntPtr ptr = bmpData.Scan0; 

      // Declare an array to hold the bytes of the bitmap. 
      int bytes = Math.Abs(bmpData.Stride) * bmp.Height; 
      byte[] rgb = new byte[bytes]; 

      // Copy the RGB values of the bitmap into the array. 
      Marshal.Copy(ptr, rgb, 0, bytes); 

      #endregion 

      #region Split rgb array into three arrays 

      // Number of colors in the image. 
      int colors = bytes/3; 

      // Declare three arrays to hold the RGB values of the bitmap. 
      byte[] r = new byte[colors]; 
      byte[] g = new byte[colors]; 
      byte[] b = new byte[colors]; 

      // Set starting pos of color index. 
      int colorIndex = 0; 

      // Split the array of RGB values into three seperate arrays. 
      for (int i = 0; i < rgb.Length; i += 3) 
      { 
       int j = i + 1, k = i + 2; 

       r[colorIndex] = rgb[k]; 
       g[colorIndex] = rgb[j]; 
       b[colorIndex] = rgb[i]; 

       colorIndex++; 
      } 

      #endregion 

      #region Hide data in the colors of the bitmap 

      for (int i = 0; i < colors; i += 2) 
      { 
       switchBits(ref r[i], ref r[i + 1]); 
      } 
      #endregion 

      #region Join the three arrays into one rgb array 

      // Reset color index. 
      colorIndex = 0; 

      // Replace the values of the rgb array with the values of the r, g and b arrays. 
      for (int i = 0; i < rgb.Length; i += 3) 
      { 
       int j = i + 1, k = i + 2; 

       rgb[k] = r[colorIndex]; 
       rgb[j] = g[colorIndex]; 
       rgb[i] = b[colorIndex]; 

       colorIndex++; 
      } 

      #endregion 

      #region Free bitmap from memory and save to file 

      // Copy the RGB values back to the bitmap 
      Marshal.Copy(rgb, 0, ptr, bytes); 

      // Unlock the bits. 
      bmp.UnlockBits(bmpData); 

      // Export the image. 
      bmp.Save("../../output.png"); 

      #endregion 
     } 

     private void switchBits(ref byte bit1, ref byte bit2) 
     { 
      byte tmp = bit1; 
      bit1 = bit2; 
      bit2 = tmp; 
     } 
    } 
} 

ich einfach nicht verstehen, warum das die Bildgröße der Bitmap ändern würde, da ich keine Farbwert am ersetzen, so dass sie nur neu anordnen.

Größe der Eingabedatei: [884 KB]

Größe der Ausgabedatei: [1335 KB]

No das Bild nicht einen Alphakanal enthält:

Image.IsAlphaPixelFormat(image.PixelFormat) == false 
+0

In welchem ​​Format sind die Ein- und Ausgabedateien: PNG wird standardmäßig eine alpha.Try dieses retten? – Reti43

+0

Sowohl Eingang als auch Ausgang haben das Format .png. Ich lade die Bitmap wie folgt: 'Bitmap bmp = new Bitmap (" ../../ input.png ");' und exportiere sie als 'bmp.Save (" ../../ output.png ") ; '@ Reti43 –

+1

Und wenn Sie die Eingabedatei laden und sofort ohne Änderung speichern, wird es die gleiche Größe wie das Original haben? – Reti43

Antwort

1

PNG verwendet (Verlustfreie Kompression. Dies bedeutet, dass die Größe der Ausgabedatei von den Daten abhängt, die Sie angeben. Bei der Komprimierung wird die Redundanz in den Daten ausgenutzt, und durch das Entfernen kann eine kleinere Größe erreicht werden. Bilder neigen dazu, eine große Redundanz aufzuweisen, da benachbarte Pixel korreliert sind, d. H. Sie haben ähnliche Werte. Was in Ihrem Fall passiert, ist, dass Ihr Shuffling etwas mit dem natürlichen Muster des Bildes interferiert, wodurch Pixelkorrelationen und Redudanz reduziert werden. Wenn es darum geht, die Daten zu komprimieren, nehmen sie mehr Platz in Anspruch.

Ich wäre nicht überrascht, wenn Sie alle Komponenten mischen würden, würden Sie bemerken, dass die Ausgabegröße noch größer wird, als nur das Rot mischen.

+0

Ich habe zwar nur die rote Komponente gemischt, aber ich habe ein paar Tests durchgeführt und es schien die Antwort zu sein. Danke, dass Sie sich die Zeit genommen haben, meine Frage zu beantworten. –

+0

@MikkelJarlund Ah, ja, mein Fehler. Für einen Moment erinnerte ich mich daran, als ob Sie alle Komponenten gewechselt hätten. In diesem Fall würde ich erwarten, dass die Größe noch größer wird. Ich habe die Antwort bearbeitet, um das richtig zu reflektieren. Übrigens, wenn eine Antwort Ihre Frage geklärt hat, haben Sie die Möglichkeit, sie als akzeptiert zu markieren (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). . – Reti43

+0

Fertig und wieder danke. Ich steige gerade in C# Entwicklung (4 Monate in) und dies ist mein erstes "großes" Projekt, also kratze ich immer noch meinen Kopf, um alles herauszufinden. Hoffentlich kann ich, wie Sie, mein Wissen in ein paar Jahren weitergeben, wenn ich ein bisschen mehr Erfahrung habe. –

0

Ihre Prüfung für Alpha ist für das Bild, nicht was gespeichert wird.

WPF - How do I save a PNG without any alpha channel?

+0

Deshalb fragte ich, ob er die Eingabedatei ohne irgendeine Änderung geladen und gespeichert hat, ob sich die Ausgabedatei in der Größe ändern würde. Es sollte Fälle erfassen, in denen der Encoder versuchen würde, mehr Informationen, die das ursprüngliche Bild hatte, aufzunehmen. Der OP sagte jedoch, er habe keinen solchen Unterschied bemerkt, daher würde ich erwarten, dass der Größenunterschied auf seine Pixelmodifikationen zurückzuführen ist. – Reti43