问题描述
如何使用 C# 内置方法或任何其他图像处理技术对带有 BMP 扩展名的图像进行异或?
How can I XOR images with BMP extension using C# built in methods or any other image processing technique?
我现在正在这样做,但我想要更有效的方法.
I'm now doing this, but I want much more efficient method.
using System;
using System.Drawing;
using System.Drawing.Imaging;
namespace IProcessing
{
/// <summary>
/// Summary description for LogicalOperator.
/// </summary>
public class LogicalOperator
{
Bitmap bmpimg;
public LogicalOperator()
{
//
// TODO: Add constructor logic here
//
}
public Bitmap XORing( Bitmap bmp )
{
BitmapData bmpData = bmpimg.LockBits( new Rectangle( 0 , 0 , bmpimg.Width , bmpimg.Height ) , ImageLockMode.ReadWrite , PixelFormat.Format24bppRgb );
BitmapData bmpData2 = bmp.LockBits( new Rectangle( 0 , 0 , bmp.Width , bmp.Height ) , ImageLockMode.ReadWrite , PixelFormat.Format24bppRgb );
int width = bmpData.Width;
int height = bmpData.Height;
if( bmpData2.Width > width )
width = bmpData2.Width;
if( bmpData2.Height > height )
height = bmpData2.Height;
bmpimg.UnlockBits( bmpData );
bmp.UnlockBits( bmpData2 );
Bitmap bit1 = new Bitmap( bmpimg , width , height );
Bitmap bit2 = new Bitmap( bmp , width , height );
Bitmap bmpresult = new Bitmap( width , height );
BitmapData data1 = bit1.LockBits( new Rectangle( 0 , 0 , bit1.Width , bit1.Height ) , ImageLockMode.ReadWrite , PixelFormat.Format24bppRgb );
BitmapData data2 = bit2.LockBits( new Rectangle( 0 , 0 , bit2.Width , bit2.Height ) , ImageLockMode.ReadWrite , PixelFormat.Format24bppRgb );
BitmapData data3 = bmpresult.LockBits( new Rectangle( 0 , 0 , bmpresult.Width , bmpresult.Height ) , ImageLockMode.ReadWrite , PixelFormat.Format24bppRgb );
unsafe
{
int remain1 = data1.Stride - data1.Width * 3;
int remain2 = data2.Stride - data2.Width * 3;
int remain3 = data3.Stride - data3.Width * 3;
byte* ptr1 = ( byte* )data1.Scan0;
byte* ptr2 = ( byte* )data2.Scan0;
byte* ptr3 = ( byte* )data3.Scan0;
for( int i = 0 ; i < height ; i ++ )
{
for( int j = 0 ; j < width * 3 ; j ++ )
{
ptr3[ 0 ] = ( byte ) ( XOR_Operator( ptr1[ 0 ] , ptr2[ 0 ] ) );
ptr1 ++;
ptr2 ++;
ptr3 ++;
}
ptr1 += remain1;
ptr2 += remain2;
ptr3 += remain3;
}
}
bit1.UnlockBits( data1 );
bit2.UnlockBits( data2 );
bmpresult.UnlockBits( data3 );
return bmpresult;
}
public byte XOR_Operator( byte a , byte b )
{
byte A = ( byte )( 255 - a );
byte B = ( byte )( 255 - b );
return ( byte )( ( a & B ) | ( A & b ) );
}
public Bitmap XNORing( Bitmap bmp )
{
// NANDing of 2 images is done by ANDing 2 images then negating the resultant
Bitmap orimg = XORing( bmp );
BitmapData data = orimg.LockBits( new Rectangle( 0 , 0 , orimg.Width , orimg.Height ) , ImageLockMode.ReadWrite , PixelFormat.Format24bppRgb );
unsafe
{
int remain = data.Stride - data.Width * 3;
byte* ptr = ( byte* )data.Scan0;
for( int i = 0 ; i < data.Height ; i ++ )
{
for( int j = 0 ; j < data.Width * 3 ; j ++ )
{
ptr[ 0 ] = invert( ptr[ 0 ] );
ptr ++;
}
ptr += remain;
}
}
orimg.UnlockBits( data );
return orimg;
}
public byte invert( byte b )
{
return ( byte )( 255 - b );
}
public void setImage( Bitmap bmp )
{
bmpimg = ( Bitmap )bmp.Clone( );
}
public Bitmap getImage( )
{
return ( Bitmap )bmpimg.Clone( );
}
}
}
推荐答案
使用 C/C++ 来实现这个内循环将大大提高速度.
The big speedup will be from using C/C++ for this inner loop.
其他选择是:
在非托管代码中,如果您使用 GDI 而不是 GDI+ 绘制,您可以使用
SetROP2()
和R2_XORPEN
.这可能比您当前的循环更快,尽管您当前的循环看起来并不太可怕.
In the unmanaged code, if you draw with GDI rather than GDI+, you can use
SetROP2()
withR2_XORPEN
. This may be faster than your current loop, although your current loop doesn't look too scary.
如果你的位图只是为了显示在屏幕上,你可以正常显示它,然后用ControlPaint.DrawReversibleLine()
If your bitmap is just for showing on the screen, you could display it normally and then draw over it with ControlPaint.DrawReversibleLine()
这篇关于如何使用 C# 的内置方法对图像进行异或?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!