C# 与IntPtr的混淆和对结构的封送

C# 与IntPtr的混淆和对结构的封送,c#,xamarin.ios,marshalling,intptr,C#,Xamarin.ios,Marshalling,Intptr,我正在学习Objective C代码,并将其转换为Xamarin iOS项目的C#代码 我正在拍摄一张UIImage,并尝试获取像素,以便获取RGB值,以便在收据上打印图像 我有这样一个结构: public struct ARGBPixel { public byte alpha; public byte red; public byte green; public byte blue;

我正在学习Objective C代码,并将其转换为Xamarin iOS项目的C#代码

我正在拍摄一张UIImage,并尝试获取像素,以便获取RGB值,以便在收据上打印图像

我有这样一个结构:

public struct ARGBPixel {
            public byte alpha;
            public byte red;
            public byte green;
            public byte blue;
        };
private NSData GetMiniData(UIImage image)
{
    NSMutableData commands = new NSMutableData ();

    int width = (int)image.Size.Width;
    int height = (int)image.Size.Height;

    var pixels = RequestImagePixelData (image);

    int w = width / 8;
    if ((width % 8) != 0)
        w++;
    int mWidth = w * 8;

    int byteWidth = mWidth / 8;

    commands.AppendBytes (new byte[]{ 0x1b, 0x40 });

    byte totalRowCount = 0;

    while (totalRowCount < height) {
        byte[] data = new byte[sizeof(byte) * byteWidth * 24];

        UInt32 pos = 0;

        for (int y = 0; y < 24; y++) {
            if (totalRowCount < height) {
                for (byte x = 0; x < byteWidth; x++) {
                    int bits = 8;

                    if ((x == byteWidth - 1) && (width < mWidth)) {
                        bits = 8 - (mWidth - width);
                    }

                    byte work = 0x00;

                    for (byte xbit = 0; xbit < bits; xbit++) {
                        work <<= 1;
                        byte[] dataBytes = new byte[2048];
                        Marshal.Copy (pixels, dataBytes, 0, Convert.ToInt32 (2048));

                        //ARGBPixel argbpixel = MarshalPixel (dataBytes [PixelIndex ((byte)(xbit + x * 8), totalRowCount, (byte)width)]);
                        //Marshal.PtrToStructure(dataBytes[PixelIndex ((byte)(xbit + x * 8), totalRowCount, (byte)width)], typeof(ARGBPixel));

                        var pix = 255;


                        if (PixelBrightness(argbpixel.red, argbpixel.green, argbpixel.blue) < 127)
                        {
                            work |= 0x01;
                        }

                    }

                    data [pos++] = work;
                }
            }

            totalRowCount++;
        }

        NSMutableData command = null;

        /*if (true) {

            command = SMPort.GenerateBitImageCommand (byteWidth, 24, data, "mini");
        }*/

        if (command != null) {
            commands.AppendData (command);
        } else {
            byte[] imageBytes = new byte[]{ 0x1b, 0x58, 0x34, 0, 24 }; // [ESC X 4]

            imageBytes [3] = (byte) byteWidth;

            commands.AppendBytes (imageBytes);

            commands.AppendBytes (data);

            byte[] printBytes = new byte[] { 0x1b, 0x58, 0x32, 24 };

            commands.AppendBytes (printBytes);
        }

        //free(data);
    }

    byte[] endingBytes = new byte[]{ 0x0c, 0x1b, 0x4A, 0x78 };

    commands.AppendBytes (endingBytes);

    //free(pixels);

    return NSData.FromBytes (commands.Bytes, commands.Length);

    //[someData release];

    //return imageData;


}

public ARGBPixel MarshalPixel(byte[] bytes)
{
    GCHandle handle = GCHandle.Alloc (bytes, GCHandleType.Pinned);

    ARGBPixel pix = (ARGBPixel)Marshal.PtrToStructure (handle.AddrOfPinnedObject (), typeof(ARGBPixel));
    handle.Free ();
    return pix;
}
我有一些代码(由提供)将获取UIImage并返回指向如下数据的指针:

protected CGBitmapContext CreateARGBBitmapContext(CGImage inImage)
{
    var pixelsWide = inImage.Width;
    var pixelsHigh = inImage.Height;
    var bitmapBytesPerRow = pixelsWide * 4;
    var bitmapByteCount = bitmapBytesPerRow * pixelsHigh;
    //Note implicit colorSpace.Dispose() 
    using(var colorSpace = CGColorSpace.CreateDeviceRGB())
    {
        //Allocate the bitmap and create context
        var bitmapData = Marshal.AllocHGlobal(bitmapByteCount);
        //I think this is unnecessary, as I believe Marshal.AllocHGlobal will throw OutOfMemoryException
        if(bitmapData == IntPtr.Zero)
        {
            throw new Exception("Memory not allocated.");
        }

        var context = new CGBitmapContext(bitmapData, pixelsWide, pixelsHigh, 8,
            bitmapBytesPerRow, colorSpace, CGImageAlphaInfo.PremultipliedFirst);
        if(context == null)
        {
            throw new Exception("Context not created");
        }
        return context;
    }
}

//Store pixel data as an ARGB Bitmap
protected IntPtr RequestImagePixelData(UIImage inImage)
{
    var imageSize = inImage.Size;
    CGBitmapContext ctxt = CreateARGBBitmapContext(inImage.CGImage);
    var rect = new RectangleF(0.0f, 0.0f, imageSize.Width, imageSize.Height);
    ctxt.DrawImage(rect, inImage.CGImage);
    var data = ctxt.Data;
    return data;
}
获取数据后,我希望通过以下操作将数据数组中的每个元素封送到
ARGBPixel

ARGBPixel argbpixel = //stuck here
代码如下所示:

public struct ARGBPixel {
            public byte alpha;
            public byte red;
            public byte green;
            public byte blue;
        };
private NSData GetMiniData(UIImage image)
{
    NSMutableData commands = new NSMutableData ();

    int width = (int)image.Size.Width;
    int height = (int)image.Size.Height;

    var pixels = RequestImagePixelData (image);

    int w = width / 8;
    if ((width % 8) != 0)
        w++;
    int mWidth = w * 8;

    int byteWidth = mWidth / 8;

    commands.AppendBytes (new byte[]{ 0x1b, 0x40 });

    byte totalRowCount = 0;

    while (totalRowCount < height) {
        byte[] data = new byte[sizeof(byte) * byteWidth * 24];

        UInt32 pos = 0;

        for (int y = 0; y < 24; y++) {
            if (totalRowCount < height) {
                for (byte x = 0; x < byteWidth; x++) {
                    int bits = 8;

                    if ((x == byteWidth - 1) && (width < mWidth)) {
                        bits = 8 - (mWidth - width);
                    }

                    byte work = 0x00;

                    for (byte xbit = 0; xbit < bits; xbit++) {
                        work <<= 1;
                        byte[] dataBytes = new byte[2048];
                        Marshal.Copy (pixels, dataBytes, 0, Convert.ToInt32 (2048));

                        //ARGBPixel argbpixel = MarshalPixel (dataBytes [PixelIndex ((byte)(xbit + x * 8), totalRowCount, (byte)width)]);
                        //Marshal.PtrToStructure(dataBytes[PixelIndex ((byte)(xbit + x * 8), totalRowCount, (byte)width)], typeof(ARGBPixel));

                        var pix = 255;


                        if (PixelBrightness(argbpixel.red, argbpixel.green, argbpixel.blue) < 127)
                        {
                            work |= 0x01;
                        }

                    }

                    data [pos++] = work;
                }
            }

            totalRowCount++;
        }

        NSMutableData command = null;

        /*if (true) {

            command = SMPort.GenerateBitImageCommand (byteWidth, 24, data, "mini");
        }*/

        if (command != null) {
            commands.AppendData (command);
        } else {
            byte[] imageBytes = new byte[]{ 0x1b, 0x58, 0x34, 0, 24 }; // [ESC X 4]

            imageBytes [3] = (byte) byteWidth;

            commands.AppendBytes (imageBytes);

            commands.AppendBytes (data);

            byte[] printBytes = new byte[] { 0x1b, 0x58, 0x32, 24 };

            commands.AppendBytes (printBytes);
        }

        //free(data);
    }

    byte[] endingBytes = new byte[]{ 0x0c, 0x1b, 0x4A, 0x78 };

    commands.AppendBytes (endingBytes);

    //free(pixels);

    return NSData.FromBytes (commands.Bytes, commands.Length);

    //[someData release];

    //return imageData;


}

public ARGBPixel MarshalPixel(byte[] bytes)
{
    GCHandle handle = GCHandle.Alloc (bytes, GCHandleType.Pinned);

    ARGBPixel pix = (ARGBPixel)Marshal.PtrToStructure (handle.AddrOfPinnedObject (), typeof(ARGBPixel));
    handle.Free ();
    return pix;
}
在这一点上我完全糊涂了。我只想能够得到像素,以便告诉什么是亮度,这将决定我的字节数组中的下一个序列作为命令馈送到我的打印机

如果这有帮助的话……以下是我试图更改的目标c代码,以便使用我的Xamarin应用程序:

- (NSData *)getImageMiniDataForPrinting:(BOOL)compressionEnable pageModeEnable:(BOOL)pageModeEnable
{
    if (imageData != nil)
    {
        return imageData;
    }

    CGImageRef cgImage = [m_image CGImage];
    int32_t width = CGImageGetWidth(cgImage);
    int32_t height = CGImageGetHeight(cgImage);

    ARGBPixel * pixels = malloc(width * height * sizeof(ARGBPixel));
    ManipulateImagePixelData(cgImage, pixels);

    if (ditheringSupported == true)
    {
        ConvertToMonochromeSteinbertDithering(pixels, width, height, 1.5);
    }

    if (pixels == NULL)
    {
        return NULL;
    }

    int w = width / 8;
    if ((width % 8) != 0)
        w++;
    int mWidth = w * 8;

    int byteWidth = mWidth / 8;

    NSMutableData *someData = [[NSMutableData alloc] init];

    if (pageModeEnable)
    {
        u_int8_t beginingBytes[] = {0x1b, 0x40,
                                    0x1b, 0x4c,
//                                  0x1b, 0x57, 0x00, 0x00, 0x00, 0x00, mWidth % 256, mWidth / 256,  height       % 256,  height       / 256,
                                    0x1b, 0x57, 0x00, 0x00, 0x00, 0x00, mWidth % 256, mWidth / 256, (height + 50) % 256, (height + 50) / 256,
                                    0x1b, 0x58, 0x32, 0x18};

        [someData appendBytes:beginingBytes length:2 + 2 + 10 + 4];
    }
    else
    {
        u_int8_t beginingBytes[] = {0x1b, 0x40};

        [someData appendBytes:beginingBytes length:2];
    }

    int totalRowCount = 0;

    while (totalRowCount < height)
    {
        u_int8_t *data = malloc(sizeof(u_int8_t) * byteWidth * 24);

        memset(data, 0, sizeof(u_int8_t) * byteWidth * 24);

        uint32_t pos = 0;

        for (int y = 0; y < 24; y++)
        {
            if (totalRowCount < height)
            {
                for (int x = 0; x < byteWidth; x++)
                {
                    int bits = 8;

                    if ((x == byteWidth - 1) && (width < mWidth))
                    {
                        bits = 8 - (mWidth - width);
                    }

                    u_int8_t work = 0x00;

                    for (int xbit = 0; xbit < bits; xbit++)
                    {
                        work <<= 1;

                        ARGBPixel pixel = pixels[PixelIndex(xbit + x * 8, totalRowCount, width)];

                        if (PixelBrightness(pixel.red, pixel.green, pixel.blue) < 127)
                        {
                            work |= 0x01;
                        }
                    }

                    data[pos++] = work;
                }
            }

            totalRowCount++;
        }

        NSMutableData *command = nil;

        if (compressionEnable)
        {
            NSString *portSettings = @"mini";

            command = [SMPort generateBitImageCommand:byteWidth :24 :data :portSettings];
        }

        if (command != nil)
        {
            [someData appendData:command];

            [command release];
        }
        else
        {
            u_int8_t imageBytes[] = {0x1b, 0x58, 0x34, 0, 24}; // [ESC X 4]

            imageBytes[3] = byteWidth;

            [someData appendBytes:imageBytes length:5];

            [someData appendBytes:data length:sizeof(u_int8_t) * byteWidth * 24];

            u_int8_t printBytes[] = {0x1b, 0x58, 0x32, 24};

            [someData appendBytes:printBytes length:4];
        }

        free(data);
    }

    u_int8_t endingBytes[] = {0x0c,
                              0x1b, 0x4A, 0x78};

    [someData appendBytes:endingBytes length:1 + 3];

    free(pixels);

    imageData = [[NSData alloc] initWithBytes:[someData mutableBytes] length:[someData length]];

    [someData release];

    return imageData;
}

u_int8_t PixelBrightness(u_int8_t red, u_int8_t green, u_int8_t blue)
{
    int level = ((int)red + (int)green + (int)blue)/3;
    return level;
}

u_int32_t PixelIndex(u_int32_t x, u_int32_t y, u_int32_t width)
{
    return (x + (y * width));
}
-(NSData*)获取用于打印的图像最小数据:(BOOL)压缩启用页面模式启用:(BOOL)页面模式启用
{
如果(imageData!=nil)
{
返回图像数据;
}
CGImageRef cgImage=[m_图像cgImage];
int32_t width=CGImageGetWidth(cgImage);
int32_t height=CGImageGetHeight(cgImage);
ARGBPixel*像素=malloc(宽度*高度*大小(ARGBPixel));
操纵图像像素数据(cgImage,像素);
如果(抖动支持==真)
{
converttonochromesteinberthering(像素、宽度、高度,1.5);
}
如果(像素==NULL)
{
返回NULL;
}
int w=宽度/8;
如果((宽度%8)!=0)
w++;
int mWidth=w*8;
int字节宽度=mWidth/8;
NSMutableData*someData=[[NSMutableData alloc]init];
如果(页面模式启用)
{
u_int8_t beginingBytes[]={0x1b,0x40,
0x1b,0x4c,
//0x1b、0x57、0x00、0x00、0x00、0x00、mWidth%256、mWidth/256、高度%256、高度/256、,
0x1b,0x57,0x00,0x00,0x00,0x00,mWidth%256,mWidth/256,(高度+50)%256,(高度+50)/256,
0x1b,0x58,0x32,0x18};
[someData appendBytes:beginingBytes长度:2+2+10+4];
}
其他的
{
u_int8_t beginingBytes[]={0x1b,0x40};
[someData appendBytes:beginingBytes长度:2];
}
int totalRowCount=0;
while(总行数<高度)
{
u_int8_t*data=malloc(sizeof(u_int8_t)*字节宽度*24);
memset(数据,0,大小(u_int8_t)*字节宽度*24);
uint32_t pos=0;
对于(int y=0;y<24;y++)
{
if(总行数<高度)
{
for(int x=0;x工作我看不到问题我编辑了问题。我想知道我是否能够从指针获取像素以及我将如何操作。您已经有了指向数据的指针,它由RequestImagePixels返回,这是一个指向数据的IntPtr。您可以使用Marshal.ReadXXX方法,也可以强制转换为字节*并对其进行操作那样。