首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在iOS 8/ iPhone 6上获取像素数据

在iOS 8/ iPhone 6上获取像素数据
EN

Stack Overflow用户
提问于 2014-09-26 11:59:17
回答 1查看 390关注 0票数 3

我需要检索位图图像的给定(x,y)坐标的像素数据。多年来,我的代码如下所示:

代码语言:javascript
运行
复制
_palettePixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage));
const UInt8 *rawData = CFDataGetBytePtr(_imagePixelData);

int pixelInfo = ((image.size.width * floorf(pointInImage.y) * image.scale) + floorf(pointInImage.x) * image.scale ) * 4;

CGFloat red   = rawData[pixelInfo + 0] / 255.0;
CGFloat green = rawData[pixelInfo + 1] / 255.0;
CGFloat blue  = rawData[pixelInfo + 2] / 255.0;
CGFloat alpha = rawData[pixelInfo + 3] / 255.0;

这在运行iPhone 4和5(而不是S)的iOS7上工作得很好。

我现在正试图让它在运行iPhone 6的iOS8上工作。要做到这一点,我需要做以下修改:

代码语言:javascript
运行
复制
int pixelInfo = ((image.size.width * floorf(pointInImage.y) * image.scale * 2) + floorf(pointInImage.x) * image.scale ) * 4;

注意代码中的额外* 2

我想知道为什么这个改变是必要的,这样我才能正确地应用它。它是链接到iOS8还是iPhone 6的64位架构?如果这是64位架构造成的,那么这是没有意义的,因为:

  1. 像素数据本身仍被编码为4个字节。
  2. 似乎是因为额外的填充而改变了每一行像素数据的宽度,但是数据在该行上的位置是相同的。例如,假设不工作8字节像素,不工作: int pixelInfo = ((image.size.width * floorf(pointInImage.y) * image.scale) + floorf(pointInImage.x) * image.scale ) * 8;

有人能弄清楚这是怎么回事吗?

EN

回答 1

Stack Overflow用户

发布于 2015-01-28 23:06:21

同样的问题把我逼上了整个星期.

我根据PNG文件中网格中的字符进行字体处理。加载时,我分析每个字符的像素,以评估准确的宽度。这段代码多年来一直运行良好,并且刚刚开始在iPhone 6(和iPad Mini)上崩溃。

这并不是由于iOS 8造成的,因为代码仍然可以在iPhone 5和iOS 8上工作。

这也不是由于编译过程的任何改变,因为我可以在模拟器和设备上重现来自同一个项目的问题。

这是多年来行之有效的代码:

代码语言:javascript
运行
复制
void PixelMap::LoadPixelData (const char * imageFile)
{
    CFStringRef filename = CFStringCreateWithCString (NULL, imageFile, kCFStringEncodingASCII),
                fileExtension = CFStringCreateWithCString (NULL, "png", kCFStringEncodingASCII);

    // Open image
    CGImageRef image = SpriteManager::CreateNamedImage (filename, fileExtension);

    CFRelease (filename);
    CFRelease (fileExtension);

    if (image == NULL)
    {
        printf ("ERROR: cannot open image \"%s\"\n", imageFile);
        return;
    }

    // Get image information
    CGImageAlphaInfo info = CGImageGetAlphaInfo (image);

    BOOL hasAlpha =
    (
        (info == kCGImageAlphaPremultipliedLast) ||
        (info == kCGImageAlphaPremultipliedFirst) ||
        (info == kCGImageAlphaLast) ||
        (info == kCGImageAlphaFirst)
    );

    PixelFormat pixelFormat;

    if (CGImageGetColorSpace (image))
    {
        if (hasAlpha)
        {
            pixelFormat = format_RGBA8888;
        }
        else
        {
            pixelFormat = format_RGB565;
        }
    }
    else  // NOTE: No colorspace means a mask image
    {
        printf ("ERROR: invalid colour space for \"%s\"\nMust be RGBA8888...\n", imageFile);
        CGImageRelease (image);

        return;
    }

    // Round dimensions up to nearest power of 2
    CGSize imageSize = CGSizeMake (CGImageGetWidth (image), CGImageGetHeight (image));

    NSUInteger width = SpriteManager::MakePowerOf2 (imageSize.width),
               height = SpriteManager::MakePowerOf2 (imageSize.height);

#ifdef DEBUG
    // Check we're not wasting resources with padding
    if (width != imageSize.width || height != imageSize.height)
    {
        printf ("WARNING: texture \"%s\" has padded width and/or height.\n", imageFile);
    }

    // Check texture size is within maximum texture size
    if (width > TEXTURE_MAX_SIZE || height > TEXTURE_MAX_SIZE)
    {
        PANIC ("Texture is too big.");
    }
#endif

    // Store dimensions
    m_width = (int)width;
    m_height = (int)height;

    // Grab the data
    if (pixelFormat == format_RGBA8888)
    {
        // Make a pixel buffer
        Allocate (width * height * 4);

        if (m_data == NULL)
        {
            printf ("ERROR: out of memory for PixelMap of \"%s\"\n", imageFile);
        }
        else
        {
            // Get the pixels
            CGColorSpaceRef colourSpace = CGImageGetColorSpace (image);

            CGContextRef context = CGBitmapContextCreate (m_data, width, height, 8, (width * 4), colourSpace, (kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big));
            CGContextDrawImage (context, CGRectMake (0, 0, CGImageGetWidth (image), CGImageGetHeight (image)), image);

            CGColorSpaceRelease (colourSpace);
            CGContextRelease (context);

#ifdef DEBUG
            printf ("Loaded pixel map from texture \"%s\"\n", imageFile);
#endif
        }
    }
    else
    {
        printf ("ERROR: invalid pixel format for \"%s\"\nMust be RGBA8888...\n", imageFile);
    }

    // Clean up the image
    CGImageRelease (image);
}

这是一种简单得多的替代方法,我最近尝试过,它产生了完全相同的效果:

代码语言:javascript
运行
复制
void PixelMap::LoadImageData (const char * imageFile)
{
    NSString * filename = [NSString stringWithUTF8String:imageFile];

    UIImage * image = [UIImage imageNamed:filename];

    m_width = (int)image.size.width;
    m_height = (int)image.size.height;

    Allocate (m_width * m_height * 4);

    CFDataRef imageData = CGDataProviderCopyData (CGImageGetDataProvider (image.CGImage));
    const UInt32 * pixels = (const UInt32 *)CFDataGetBytePtr (imageData);

    memcpy (m_data, pixels, m_dataSize);

    CFRelease (imageData);
}

这是我传递给这个函数的字体图像示例:

研究实现这一功能的任何一种方式的输出都会产生以下结果:

在iPhone 5上(正确).

代码语言:javascript
运行
复制
Pixel Map Dump [64, 128 -> 128, 192]

                           ************                         
                         ****************                       
                       ********************                     
                      **********************                    
                     ***********************                    
                     ************************                   
                     ************************                   
                    *************************                   
                    *************************                   
                    *************************                   
                    *************************                   
                    *************************                   
                     ************************                   
                     ************************                   
                     ***********************                    
                     ***********************                    
                      *********************                     
                      *********************                     
                       *******************                      
                       *******************                      
                        *****************                       
                        *****************                       
                        *****************                       
                        *****************                       
                        *****************                       
                        ****************                        
                        ****************                        
                        ****************                        
                        ****************                        
                        ****************                        
                         **************                         
                          ***********                           
                            **********                          
                          *************                         
                         ***************                        
                        *****************                       
                        ******************                      
                       *******************                      
                       ********************                     
                       ********************                     
                      *********************                     
                      *********************                     
                      *********************                     
                      *********************                     
                      *********************                     
                      *********************                     
                      *********************                     
                      *********************                     
                       ********************                     
                       *******************                      
                        ******************                      
                         ***************                        
                          ************                          

...and和iPhone 6..。

代码语言:javascript
运行
复制
Pixel Map Dump [64, 128 -> 128, 192]

        **************                       *********          
       *****************                    **************      
       ******************                 ****************      
       ******************                 ****************      
       ******************                *****************      
        *****************               ******************      
         ****************               ******************      
         ****************              *******************      
         ***************               ***********  ******      
         ****************              **********    ****       
         *****************             **********               
         ******************           ***********     ***       
        *******************           ***********   ******      
        ********************          ************ *******      
        ********************          ********************      
        ********************          ********************      
        ********************           *******************      
       *********************           *******************      
       *********************           *******************      
      **********************           *******************      
     ***********************            ******************      
     **********************              *****************      
     **********************              *****************      
     *********************                ***************       
      ******************                    ************        
         ************                         *******           






      ***************                      *************        
     ******************                   **************        
     *******************                 ****************       
     *******************                *****************       
     *******************                *****************       
     *******************                *****************       
      ******************                *****************       
      ******************                ****************        
       ****************                 **************          
      *****************                 ****************        
      ****************                   ****************       
      ******************                  ***************       
      *******************                  ***************      
      ********************                  **************      
      ********************             ***** *************      
      ********************            ********************      
     **********************           ********************      
     **********************           ********************      
     **********************           ********************      
    ************************          ********************      
   *************************          ********************      
   **************************          ******************       
   **************************          *****************        
   **************************           ****************        
    *************************            *************          
      **********    *******                 ********            

正如你所看到的,所得到的像素数据基本上已经被缩放了1/2。一段时间以来,我一直在指责颜色空间,但这似乎不是罪魁祸首。

我读过的(很多)页面之一让我觉得iPhone 6和其他显示这个问题的设备在幕后使用64位,而不是通常的32位(尽管我试图强迫32 BPP离开)。

跳到“深奥的布局”:http://www.objc.io/issue-3/moving-pixels-onto-the-screen.html

我真的不想做'if‘(iPhone6 \x\\ iPadMini)做’黑客‘类型的事情,但老实说,我已经厌倦了把这个问题干干净净地解决掉。

也可能相关:iPhone 6 Plus resolution confusion: Xcode or Apple's website? for development

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26059049

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档