2013-12-06 3 views
0
private void ReadImage() 
    { 
     int i, j; 
     GreyImage = new int[Width, Height]; //[Row,Column] 
     Bitmap image = Obj; 
     BitmapData bitmapData1 = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), 
           ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); 
     unsafe 
     { 
      byte* imagePointer1 = (byte*)bitmapData1.Scan0; 

      for (i = 0; i < bitmapData1.Height; i++) 
      { 
       for (j = 0; j < bitmapData1.Width; j++) 
       { 
        GreyImage[j, i] = (int)((imagePointer1[0] + imagePointer1[1] + imagePointer1[2])/3.0); 
        //4 bytes per pixel 
        imagePointer1 += 4; 
       }//end for j 
       //4 bytes per pixel 
       imagePointer1 += bitmapData1.Stride - (bitmapData1.Width * 4); 
      }//end for i 
     }//end unsafe 
     image.UnlockBits(bitmapData1); 
     return; 
    } 

линия GreyImage[j,i] = (int)((imagePointer1[0] ..... кажется, что читает в byte* как массив, очевидно, я не могу назначить небезопасное бит кода в массив для дальнейшей обработки, поэтому я думал, может быть, просто назначить эти 4 байта в массив.Пытаясь понять эту функцию Image

Как вы назначаете эти 4 байта массиву?

я думал, выполнив:

var imageData = new byte[Width, Height][]; 
imageData[x,y] = pixelSet //basically byte[]; 

Любые идеи

ответ

1

Я думаю, что вы пытаетесь сделать что-то вроде этого. Очевидно, что я не тестировал этот код, но он доставит вас в том направлении, в котором вы хотите.

byte[] save = new byte[4]; 
Array.Copy(*imagePointer1, save, 4); 

ИЛИ

byte[] save = new byte[4]; 
save[0] = bitmapData1.Scan0[0]; 
save[1] = *(imagePointer1 + 1); 
save[2] = *(imagePointer1 + 2); 
save[3] = *(imagePointer1 + 3); 

Указатель на массив всегда указывает на нулевой элемент.Вы можете получить доступ к другим элементам, добавив указатель или увеличив указатель.

(imagePointer1 + 5) // pointer to 5th element 
*(imagePointer1 + 5) // value of 5th element 
    imagePointer1 += 5; // imagePointer1 now starts at element 5 

Плюс и минус перемещают ссылку указателя на количество байтов, которые составляют размер массива данных массива. Если бы это был int [], + и -, то он переместил бы указатель с шагом в 4 байта.

Я надеюсь, что это поможет вам.

+0

Да, это именно то, что я ищу, я нашел что-то подобное в своих путешествиях по Google, однако, когда дело дошло до выбора размера массива 'byte []', я понятия не имел, поэтому я был как " как вы получаете это из «imagePointer», поэтому я думаю, что я понимаю, что imagePointer - это все изображение справа. –

+0

yes, imagePointer1 - это указатель на bitmapData1.Scan0 [0]. Если вы попытаетесь прочитать прошлое bitmapData1.Scan0.Length, у вас возникнут проблемы. – drankin2112

0

Функция должна преобразовать изображение в оттенках серого один, и сохранить значения цвета в GreyScale массив. Но в этой функции есть ошибка (фактически 2).

Прежде всего, вы только прочитать верхний левый пиксель вашего изображения, вместо этого вы должны использовать это:

GreyImage[j, i] = (int)((imagePointer1[j * 4 + i * bitmapData1.Width * 4] + imagePointer1[j * 4 + i * bitmapData1.Width * 4 + 1] + imagePointer1[j * 4 + i * bitmapData1.Width * 4 + 2])/3.0); 

Другое дело, что все цвета не являются «равными», когда вы превращаете ваш изображения, вы можете найти обычные факторы, применяемые к красным, зеленым и синим каналам, чтобы довольно легко преобразовать в оттенки серого в Google.

И чтобы ответить на ваш вопрос, то, как это делается в вашей функции, чтобы присвоить значение вашему массиву, является правильным.

EDIT

ответить вам комментарии:

В скобках [] я вычислить смещение в массиве, где цвет информация о пикселе в точке с координатами (j, i) АРЕ. (Кстати, мы обычно используем i для x и j для y, здесь все наоборот)

Допустим, вы хотите знать значения цвета пикселя в точке с координатами x = 2, y = 4, вам необходимо использовать следующую формулу:

color = y * <number of bytes per line> + x

Поскольку ваше изображение является 32-битным, с приведенной выше формулой вы получите красное значение цвета. Если вы хотите зеленую вы добавляете 1, для синего вы добавляете 2.

В части кода, который я разместил, я предполагаю, что каждая строка займет ровно width * 4 байт, это верно большую часть времени для 32-битных изображений , но не всегда, так что лучше использовать эту формулу на самом деле:

[imagePointer[i * bitmapData1.Stride + j]

+0

Я не хочу хранить шкалу серого, я хочу, чтобы 4 байта составляли изображение в новом массиве, например, я указываю в нижней части моего ответа, спасибо за разъяснение проблем, очень ценю –

+0

@ No1_Melman. Вы можете использовать один и тот же фрагмент кода, просто удалите '/ 3.0' в конце строки. – ppetrov

+0

. Большое спасибо, не могли бы вы просто объяснить немного больше, что вы сделали внутри' [] 'imagePointer1, объяснение используемых чисел или используемых переменных. Благодарю. –

Смежные вопросы