从原始图像中获取意外的像素

时间:2014-01-06 21:22:10

标签: ios objective-c bitmap core-foundation bytebuffer

我试图从游戏场景中的某些像素中捕捉R,G和B.为此我在Black& amp;中创建了一个Bitmap图像。白。

首先在Init()上加载此图像,然后检查每个精灵移动是否真的是一个可用的点。

问题是我在R,G和B处获得了意外数据。我尝试了两个Bitmap图像(8位和24位)。它们都只有黑白像素。但r,g和b一直告诉我这些像素是任何其他颜色。我认为" no_of_channels"应该是3,因为我不使用alpha通道,对吧?有任何想法吗?

App.h

// background mask
UIImage* bgmask;
CGImageRef aCGImageRef;
CFDataRef rawData;
UInt8 * bgmaskbuf;

初​​始化():

    // BG Mask
    bgmask = [UIImage imageNamed:@"mask.bmp"];
    aCGImageRef = bgmask.CGImage;

    rawData = CGDataProviderCopyData(CGImageGetDataProvider(aCGImageRef));
    bgmaskbuf = (UInt8 *) CFDataGetBytePtr(rawData);

检查Pixel数据的方法:

-(BOOL) checkPixel: (CGFloat)x : (CGFloat)y{

BOOL result = FALSE;


//int length = CFDataGetLength(rawData);

//for(int i=0; i<length; i+=3)
//{
//    int r = bgmaskbuf[i];
//    int g = bgmaskbuf[i+1];
//    int b = bgmaskbuf[i+2];

//    NSLog(@"Ptr: %d, R: %d, G: %d, B: %d", i, r, g, b);
//}


int no_of_channels = 3;
int image_width = SCREEN_WIDTH();

unsigned long row_stride = image_width * no_of_channels; // 960 bytes in this case
unsigned long x_offset = x * no_of_channels;

/* assuming RGB byte order (as opposed to BGR) */
row_stride * (int)y + x_offset
int r = bgmaskbuf[next_pixel];
int g = bgmaskbuf[next_pixel + 1];
int b = bgmaskbuf[next_pixel + 2];
NSLog(@"Ptr: %d, R: %d, G: %d, B: %d",next_pixel r, g, b);

if((r==0)&&(g==0)&&(b==0)){
    result = TRUE;
}

    return result;
}

如何解决这个问题? 感谢。

关注这个问题:

以下是我试图解决的问题:

在像素检查时,我尝试运行内部的每个像素:

int length = CFDataGetLength(rawData);

for(int i=0; i<length; i+=3)
{
    int r = bgmaskbuf[i];
    int g = bgmaskbuf[i+1];
    int b = bgmaskbuf[i+2];

    NSLog(@"Ptr: %d, R: %d, G: %d, B: %d", i, r, g, b);
}

长度为786432,这是有意义的(1024 * 768像素)。我可以看到/读取所有像素,总共2359296个字节(R + G + B)。

现在,奇怪的是,在处理用户的触摸和移动时,793941等数据缓冲区索引给了我EXC_BAD_ACCESS,地址为0x13200555。

当我尝试读取它时会发生这种情况:

row_stride * (int)y + x_offset
int r = bgmaskbuf[next_pixel];
int g = bgmaskbuf[next_pixel + 1];
int b = bgmaskbuf[next_pixel + 2];

bgmaskbuf从0x13240000开始。

因此,地址范围从0x13240000到0x13480000应该是可读的。

但我刚刚读过同一个地址!

2 个答案:

答案 0 :(得分:0)

您需要检查一些值。行步幅实际上可能实际上不是图像宽度和通道数。他们喜欢填充行以保持它们的边界。您应该能够从图像中获取该信息。要检查你是否可以看到checkpixel在顶部/底部行上是否正常工作(某些图像也在内存中颠倒)以查看值是否正确。

答案 1 :(得分:0)

对我有用的是什么:

  • 仅将位图图像保存为1位(执行此操作的最佳和最简单的方法是使用Paint,我无法找到Mac应用程序)。
  • 生成的蒙版确实从屏幕图像旋转了180度。

为此,我只使用了1个频道:

-(BOOL) checkPixel: (CGFloat)x : (CGFloat)y{

BOOL result = FALSE;

int no_of_channels = 1;
int image_width = SCREEN_WIDTH();

unsigned long row_stride = image_width * no_of_channels; // 960 bytes in this case
unsigned long x_offset = x * no_of_channels;


row_stride * (int)y + x_offset
int pixie = bgmaskbuf[next_pixel];

if(pixie==0)){
    result = TRUE;
}

而不是代码旋转蒙版,我认为图像编辑更容易=)

谢谢大家!