2010-04-24 18 views
6

C# kullanıyorum ve Bitmap nesnesinde saklanan bir görüntü var.Bitmap bit boyutunun azaltılması C#

Şimdi bu resmi 8 bit gri tonlamalı, ardından 4 bit gri tonlamalı bir resme dönüştürmek istiyorum.

Bunun nasıl yapılabileceği konusunda herhangi bir ipucu var mı?

cevap

6

.NET Bitmap biçimlerinde, 8 veya 4 bit gri tonlamalı resim gibi bir şey yoktur. Desteklenen formatlar PixelFormat enumeration numarasında numaralandırılmıştır. Bununla birlikte, endeksli bir görüntü (8bppIndexed veya 4bppIndexed) oluşturarak 4 veya 8 bitlik bir görüntü oluşturabilir, burada paletteki her bir giriş gri tonlamalı bir değerdir.

Bu kod, bir Bitmap alır ve gri tonlama değerleriyle bir 8bpp endeksli görüntü olarak bir kopyasını oluşturur: yerine 4Bpp görüntü yapabilmek için

public static Bitmap BitmapToGrayscale(Bitmap source) 
    { 
     // Create target image. 
     int width = source.Width; 
     int height = source.Height; 
     Bitmap target = new Bitmap(width,height,PixelFormat.Format8bppIndexed); 
     // Set the palette to discrete shades of gray 
     ColorPalette palette = target.Palette;    
     for(int i = 0 ; i < palette.Entries.Length ; i++) 
     {     
      palette.Entries[i] = Color.FromArgb(0,i,i,i); 
     } 
     target.Palette = palette; 

     // Lock bits so we have direct access to bitmap data 
     BitmapData targetData = target.LockBits(new Rectangle(0, 0, width,height), 
               ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); 
     BitmapData sourceData = source.LockBits(new Rectangle(0, 0, width,height), 
               ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 

     unsafe 
     { 
      for(int r = 0 ; r < height ; r++) 
      { 
       byte* pTarget = (byte*) (targetData.Scan0 + r*targetData.Stride); 
       byte* pSource = (byte*) (sourceData.Scan0 + r*sourceData.Stride); 
       for(int c = 0 ; c < width ; c++) 
       { 
        byte colorIndex = (byte) (((*pSource)*0.3 + *(pSource + 1)*0.59 + *(pSource + 2)*0.11)); 
        *pTarget = colorIndex; 
        pTarget++; 
        pSource += 3; 
       } 
      } 
     } 

     target.UnlockBits(targetData); 
     source.UnlockBits(sourceData); 
     return target; 
    } 

, sen PixelFormat ile hedef oluşturmak gerekir. Format4bppIndexed ve sonra ColorPalette 16 gri ayrık tonlarını ayarlayın. Son olarak, döngüde, değerler 2'yi 0-15 arasında olmalı ve her 2 piksel değerini tek bir bayta paketlemelisiniz.

Bu

bir 4bpp gri tonlu görüntü yapmak için modifiye kodudur:

BitmapToGrayscale4bpp` `son kısmı bir küçük hata vardır
public static Bitmap BitmapToGrayscale4bpp(Bitmap source) 
    { 
     // Create target image. 
     int width = source.Width; 
     int height = source.Height; 
     Bitmap target = new Bitmap(width,height,PixelFormat.Format4bppIndexed); 
     // Set the palette to discrete shades of gray 
     ColorPalette palette = target.Palette;    
     for(int i = 0 ; i < palette.Entries.Length ; i++) 
     { 
      int cval = 17*i; 
      palette.Entries[i] = Color.FromArgb(0,cval,cval,cval); 
     } 
     target.Palette = palette; 

     // Lock bits so we have direct access to bitmap data 
     BitmapData targetData = target.LockBits(new Rectangle(0, 0, width,height), 
               ImageLockMode.ReadWrite, PixelFormat.Format4bppIndexed); 
     BitmapData sourceData = source.LockBits(new Rectangle(0, 0, width,height), 
               ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); 

     unsafe 
     { 
      for(int r = 0 ; r < height ; r++) 
      { 
       byte* pTarget = (byte*) (targetData.Scan0 + r*targetData.Stride); 
       byte* pSource = (byte*) (sourceData.Scan0 + r*sourceData.Stride); 
       byte prevValue = 0; 
       for(int c = 0 ; c < width ; c++) 
       { 
        byte colorIndex = (byte) ((((*pSource)*0.3 + *(pSource + 1)*0.59 + *(pSource + 2)*0.11))/16); 
        if (c % 2 == 0) 
         prevValue = colorIndex; 
        else 
         *(pTarget++) = (byte)(prevValue | colorIndex << 4); 

        pSource += 3; 
       } 
      } 
     } 

     target.UnlockBits(targetData); 
     source.UnlockBits(sourceData); 
     return target; 
    } 
+0

:' (bayt) (prevValue | Colorındex << 4) '' olmalı (bayt) (prevValue << 4 | colorIndex) '. PrevValue nibble, çıktı baytındaki colorIndex nibble'dan önce gelmelidir. – lnmx

İlgili konular