我正在使用Objective C代码并将其转换为我的Xamarin iOS项目的C#代码。
我正在拍摄UIImage并尝试获取像素以获取RGB值,以便我可以在收据上打印图像。
我有一个看起来像这样的结构:
public struct ARGBPixel {
public byte alpha;
public byte red;
public byte green;
public byte blue;
};
我有一些代码(由here提供)将采用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
代码如下所示:
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;
}
此处有更多代码:
byte PixelBrightness(byte red, byte green, byte blue)
{
int level = ((int)red + (int)green + (int)blue)/3;
return (byte)level;
}
UInt32 PixelIndex(UInt32 x, UInt32 y, UInt32 width)
{
return (UInt32)(x + (y * width));
}
此时我完全感到困惑。我只是希望能够得到像素,以便知道亮度是多少,这将决定我的字节数组中的下一个序列作为命令提供给我的打印机......
如果这有帮助......这里是我想要更改的目标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));
}
我的问题是如何从指针中获取结构数组(像素) - 所以我想将一个点更改为一个结构数组?