2010-02-10 2 views
0

У меня есть два растровых изображения 8bpp. Я хочу сделать побитовое И от одного к другому, но я не вижу очевидного способа сделать это в .NET. Можно ли это сделать без использования методов не.NET? Спасибо!Булевая растровая операция в .NET?

+0

Указано ли 8bpp? Это означает, что имеется 256 цветов, но/которые/они указаны в отдельной таблице, в которую каждый пиксель индексируется. .NET вызывает это Format8bppIndexed. –

+0

Нет, это всего лишь один канал, извлеченный из более глубокого изображения. – user20493

+0

Хм, я не уверен, является ли это одним из поддерживаемых значений PixelFormat. –

ответ

3

Я думаю, что вы ищете Bitmap.LockBits.

+0

Возможно, мне придется прибегнуть к этому, если я не могу найти библиотечный метод, который это делает. К сожалению, цикл в C#, вероятно, будет выполняться медленнее. – user20493

1

Если производительность не важна, используйте Bitmap.GetPixel и Bitmap.SetPixel

+0

К сожалению, в .NET они очень медленные. – user20493

3

Вы можете попробовать преобразовать растровое изображение в массив байтов, а затем петлю через байты Андинг их вместе

Edit: Ран тест времени на идее цикла:

Пример кода:

DateTime StartTime = DateTime.Now; 
Image Image1 = Image.FromFile("C:\\Image1.bmp"); 
Image Image2 = Image.FromFile("C:\\Image2.bmp"); 
DateTime AfterLoad = DateTime.Now; 
MemoryStream S = new MemoryStream(); 
Image1.Save(S, System.Drawing.Imaging.ImageFormat.Bmp); 
Byte[] I1 = S.ToArray(); 
Image2.Save(S, System.Drawing.Imaging.ImageFormat.Bmp); 
Byte[] I2 = S.ToArray(); 
DateTime AfterConvert = DateTime.Now; 
DateTime AfterLoop = DateTime.Now; 
if (I1.Length == I2.Length) 
{ 
    Byte[] I3 = new Byte[I1.Length]; 
    for (int i = 0; i < I1.Length; i++) 
     I3[i] = Convert.ToByte(I1[i] & I2[i]); 
    AfterLoop = DateTime.Now; 
    FileStream F = new FileStream("C:\\Users\\jamesb\\desktop\\Image3.bmp", FileMode.OpenOrCreate); 
    F.Write(I3, 0, I3.Length); 
    F.Close(); 
} 
DateTime Finished = DateTime.Now; 
MessageBox.Show("Load Time: " + (AfterLoad - StartTime).TotalMilliseconds.ToString() + " ms" + "\r\n" + 
       "Convert Time: " + (AfterConvert - AfterLoad).TotalMilliseconds.ToString() + " ms"+ "\r\n" + 
       "Loop Time: " + (AfterLoop - AfterConvert).TotalMilliseconds.ToString() + " ms"+ "\r\n" + 
       "Save Time: " + (Finished - AfterLoop).TotalMilliseconds.ToString() + " ms"+ "\r\n" + 
       "Total Time: " + (Finished - StartTime).TotalMilliseconds.ToString() + " ms"); 

со следующими результатами:

Load Time: 30.003 ms 
Convert Time: 94.0094 ms 
Loop Time: 128.0128 ms 
Save Time: 177.0177 ms 
Total Time: 429.0429 ms 

Изображения «Изображение1» и «Image2» были 4000 х 2250 (с цифровой камеры преобразуются в 8 бит BMP)

+0

Интересный подход. К сожалению, цикл C# медленный. – user20493

1

Вы можете использовать функцию «BitBlt», в котором вы можете и источник и пункт назначения (SRCAND), подпись pinvoke here.

Вот статья о Codeproject, которая использует обертку BitBlt here.

Надеюсь, это поможет, С уважением, Tom.

+0

Он попросил сделать это, не используя методы не.NET. –

+0

@Matthew ... к сожалению ... существует зависимость от pinvoke, чтобы делать некоторые вещи, которые .NET не может сделать .... – t0mm13b

+0

Нет никакой причины, по которой .NET не может этого сделать. –

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