2017-02-15 68 views
0

我有一张图片被分成四部分,我想通过RGB改变颜色,但只改变了一半。 1.change当图片宽度小于256时失败。 2.my小图片最大不超过256. 3.每张256 * 256的图片都是正常的。 4.问题值:r = 0,g = 0,b = 52。c#改变图片的颜色,但只改变half.by gdi +

private void Adjust(Bitmap pBitmap, params int[] pValues) 
    { 
     BitmapData pBitmapData = pBitmap.LockBits(
      new Rectangle(0, 0, pBitmap.Width, pBitmap.Height), 
      ImageLockMode.ReadWrite, 
      PixelFormat.Format24bppRgb); 

     byte[] pData = new byte[pBitmapData.Stride * pBitmap.Height]; 
     Marshal.Copy(pBitmapData.Scan0, pData, 0, pData.Length); 
     pBitmap.UnlockBits(pBitmapData); 

     int iOffset = pBitmapData.Stride - pBitmapData.Width * 3; 
     int iIndex = 0; 

     for (int i = 0; i < pBitmapData.Height; i++) 
     { 
      for (int j = 0; j < pBitmapData.Width; j++) 
      { 
       for (int k = iIndex; k < iIndex + 3; k++) 
       { 
        pData[k] = Adjust(pData[k], k); 
       } 
       iIndex += 3; 
      } 
      iIndex += iOffset; 
     } 

     Marshal.Copy(pData, 0, pBitmapData.Scan0, pData.Length); 
     //pBitmap.UnlockBits(pBitmapData); 
    } 


protected byte Adjust(byte iValue, int iIndex) 
     { 
      int nColour = 0; 

      switch (iIndex % 3) 
      { 
       case 0: 
        nColour = (int)iValue + m_iBlue; 
        break; 
       case 1: 
        nColour = (int)iValue + m_iGreen; 
        break; 
       case 2: 
        nColour = (int)iValue + m_iRed; 
        break; 
      } 


      return nColour; 
     } 

原始照片,而无需使用问题参数:使用问题参数

enter image description here

原始图像改变颜色:

enter image description here

+0

我稍微被这里的标记有关 - GDI +从未在asp.net背景下官方支持。 –

+0

我认为增加步幅差异会让它变得混乱。如果iOffset不是3的倍数,那么您的k%3将不会在第一行之后的0,1,2的顺序中。 – Nyerguds

回答

0

你的问题,正如我所说在我的评论中,大步有可能会弄乱%3部分,所以你应该将您正在阅读的颜色分量作为单独的数字传递,而不是完整的偏移量。无论如何,该函数不需要或使用该偏移量。

在一个相关的说明中,我认为最简单的在字节上迭代图像的方法就是循环遍历X和Y,然后计算循环内的真实偏移量。

for (Int32 y = 0; y < pBitmapData.Height; y++) 
{ 
    for (Int32 x = 0; x < pBitmapData.Width; x++) 
    { 
     Int32 offset = y * pBitmapData.Stride + x * 3 
     for (int k = 0; k < 3; k++) 
     { 
      Int32 colOffset = offset + k; 
      pData[colOffset] = Adjust(pData[colOffset], k); 
     } 
    } 
} 

这样一来,你可以做实际的k值的情况下,交换机为0/1/2,而不是(偏移+ k)的3%,其中有没有保证是第一个正确后因为步长通常将四舍五入为四个字节的倍数。

最后......做边界检查。您正在编辑字节和那些只能去从0到255

protected Byte Adjust(Byte value, Int32 colourComponent) 
{ 
    Int32 newColour = 0; 
    switch (colourComponent) 
    { 
     case 0: 
      newColour = value + m_iBlue; 
      break; 
     case 1: 
      newColour = value + m_iGreen; 
      break; 
     case 2: 
      newColour = value + m_iRed; 
      break; 
    } 
    return (Byte)Math.Max(Math.Min(nColour, 255), 0); 
} 
+0

虽然您的解决方案不可用,但我已用emgucv.thanks解决了它 –

+0

可用?咦? – Nyerguds