How images can be XOR using C#'s builtin methods?

走远了吗. 提交于 2019-12-24 12:08:03

问题


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( );
    }
}
}

回答1:


The big speedup will be from using C/C++ for this inner loop.

Other alternatives would be:

  1. In the unmanaged code, if you draw with GDI rather than GDI+, you can use SetROP2() with R2_XORPEN. This may be faster than your current loop, although your current loop doesn't look too scary.

  2. If your bitmap is just for showing on the screen, you could display it normally and then draw over it with ControlPaint.DrawReversibleLine()




回答2:


Xor can be done with "^" operator. Eg. "result = a ^ b"



来源:https://stackoverflow.com/questions/2040174/how-images-can-be-xor-using-cs-builtin-methods

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!