2013-10-05 61 views
0

我在使用鎖定位寫入文件時遇到問題。我正在研究邊緣檢測軟件,它對大多數圖像都有奇怪的失真效果。我試圖找出問題,看起來很隨意。它與格式無關,而是似乎工作的唯一圖像是用於桌面壁紙的圖片,而我不知道爲什麼。我只是最近纔開始使用鎖定位來寫文件,所以我確信問題在於(當我用鎖定位讀取並使用設置像素進行讀取時沒有問題)。下面是效果截圖:帶鎖定位的圖像失真

Screenshot

正如你所看到的,邊緣檢測工作,但圖像失真水平,使圖像成平行四邊形。

下面是處理所有這(在C#)方法的代碼片段:

private void analyze() 
{ 
    //When the analyze button is pressed 
    percentageInt = float.Parse(textBox1.Text); 
    float scale = 1; 

    if (comboBox1.SelectedItem == "Auto") 
    { 
     scale = pic.Width/pictureBox1.Width; 
    } 
    else if (comboBox1.SelectedItem == "1/2") 
    { 
     scale = 2; 
    } 
    else if (comboBox1.SelectedItem == "1/4") 
    { 
     scale = 4; 
    } 
    else if (comboBox1.SelectedItem == "Original") 
    { 
     scale = 1; 
    } 
    else 
    { 
     scale = pic.Width/pictureBox1.Width; 
    } 

    int tempWidth = 1; 
    int tempHeight = 1; 
    if (scale >= 1) 
    { 
     tempWidth = (int)Math.Floor(pic.Width/scale); 
     tempHeight = (int)Math.Floor(pic.Height/scale); 
    } 
    else 
    { 
     tempWidth = pic.Width; 
     tempHeight = pic.Height; 
    } 

    width = pic.Width; 
    height = pic.Height; 
    edgeData = new Boolean[pic.Width, pic.Height]; 

    img = (Bitmap)resizeImage(pic, new Size(tempWidth, tempHeight)); 
    pic2 = new Bitmap(tempWidth, tempHeight); 
    Bitmap img2 = (Bitmap)pic2; 
    Color[] pixels = null; 

    BitmapData data = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), 
      ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); 

    int size = Math.Abs(data.Stride) * img.Height; 
    Byte[] bytes = new byte[size]; 

    int scaledPercent = (int)(Math.Round(percentageInt * 255)); 
    Debug.WriteLine("percent " + scaledPercent); 
    unsafe 
    { 
     Debug.WriteLine("Woah there, unsafe stuff"); 
     byte* prevLine = (byte*)data.Scan0; 
     byte* currLine = prevLine + data.Stride; 
     byte* nextLine = currLine + data.Stride; 

     for (int y = 1; y < img.Height - 1; y++) 
     { 
      byte* pp = prevLine + 3; 
      byte* cp = currLine + 3; 
      byte* np = nextLine + 3; 
      for (int x = 1; x < img.Width - 1; x++) 
      { 
       if (IsEdgeOptimized(pp, cp, np, scaledPercent)) 
       { 
        edgeData[x, y] = true; 
        //Debug.WriteLine("x " + x + "y " + y); 

        //img2.SetPixel(x, y, Color.Black); 
        //bytes[(y * img.Width + x) * 3 + 2] = 255; 
       } 
       else 
       { 
        bytes[(y * img.Width + x) * 3] = 255; 
        bytes[(y * img.Width + x) * 3 + 1] = 255; 
        bytes[(y * img.Width + x) * 3 + 2] = 255; 
        //img2.SetPixel(x, y, Color.White); 
       } 
       pp += 3; cp += 3; np += 3; 
      } 
      prevLine = currLine; 
      currLine = nextLine; 
      nextLine += data.Stride; 
     } 
    } 
    System.Runtime.InteropServices.Marshal.Copy(bytes, 0, data.Scan0, size); 
    img.UnlockBits(data); 
    pictureBox2.Image = img; 
} // end analyze 

那麼是什麼原因造成的問題,以及如何解決它?如果您需要更多的細節,請隨時發表評論。

+0

它看起來像圖像有一個alpha通道,所以你有32位每像素,而不是24 – thumbmunkeys

+0

我認爲這是,但我遇到了這個問題與JPG圖像,它不能支持透明度。 – vkoves

回答

1

你初始化你的字節步幅x高緩衝區的字節:

int size = Math.Abs(data.Stride) * img.Height; 
Byte[] bytes = new byte[size]; 

但是如果使用寬度(而不是步幅)當你寫它:

bytes[(y * img.Width + x) * 3] = 255; 
+0

用data.Stride替換img.Width導致indexOutOfBounds異常,爲什麼? – vkoves

+0

您將整個偏移量乘以3而不是僅乘以x。嘗試「bytes [y * data.Stride + x * 3] = 255;」。 – Chris

+0

請記住,步幅是字節/行,而不是像素! – Chris