الحصول على بيانات البكسل من UiimageView - Works على محاكي، وليس الجهاز

StackOverflow https://stackoverflow.com/questions/1911360

  •  19-09-2019
  •  | 
  •  

سؤال

بناء على الردود على سؤال سابق, لقد قمت بإنشاء فئة على UiimageView لاستخراج بيانات البكسل. هذا يعمل بشكل جيد في محاكاة، ولكن ليس عند النشر على الجهاز. يجب أن أقول لا دائما - الشيء الغريب هو أنه يحصل على لون بكسل الصحيح إذا Point.x == Point.y؛ خلاف ذلك، فإنه يعطيني بيانات البكسل لحضور بكسل على الجانب الآخر من هذا الخط، كما لو كانت معكوسة. (لذلك فإن الصنبور على بكسل في الركن الأيمن السفلي من الصورة يعطيني بيانات البكسل لحضور البكسل المقابلة في الجزء العلوي الأيسر، ولكن النقر على بكسل في الزاوية اليسرى السفلى ترجع لون بكسل الصحيح). الإحداثيات التي تعمل باللمس (CGPOINT) صحيحة.

ما الخطأ الذي افعله؟

إليك الرمز الخاص بي:

@interface UIImageView (PixelColor)
- (UIColor*)getRGBPixelColorAtPoint:(CGPoint)point;
@end

@implementation UIImageView (PixelColor)

- (UIColor*)getRGBPixelColorAtPoint:(CGPoint)point
{
    UIColor* color = nil;

    CGImageRef cgImage = [self.image CGImage];
    size_t width = CGImageGetWidth(cgImage);
    size_t height = CGImageGetHeight(cgImage);
    NSUInteger x = (NSUInteger)floor(point.x);
    NSUInteger y = height - (NSUInteger)floor(point.y);

    if ((x < width) && (y < height))
    {
        CGDataProviderRef provider = CGImageGetDataProvider(cgImage);
        CFDataRef bitmapData = CGDataProviderCopyData(provider);
        const UInt8* data = CFDataGetBytePtr(bitmapData);
        size_t offset = ((width * y) + x) * 4;
        UInt8 red = data[offset];
        UInt8 blue = data[offset+1];
        UInt8 green = data[offset+2];
        UInt8 alpha = data[offset+3];
        CFRelease(bitmapData);
        color = [UIColor colorWithRed:red/255.0f green:green/255.0f blue:blue/255.0f alpha:alpha/255.0f];
    }

    return color;
}
هل كانت مفيدة؟

المحلول

أعتقد R. بي جي خطأ. لديك:

UInt8 red =   data[offset];     
UInt8 blue =  data[offset+1];
UInt8 green = data[offset+2];

ولكن لا تقصد حقا ص غيظ? :

UInt8 red =   data[offset];     
UInt8 green = data[offset+1];
UInt8 blue =  data[offset+2];

ولكن حتى مع تلك الثابتة، لا تزال هناك مشكلة أثناء تشغيل Apple بايت مقايضات (مقالة رائعة) القيم R و B عند الجهاز، ولكن ليس عندما على محاكاة.

كان لدي مشكلة محاكاة / جهاز مماثلة مع عازلة PNG's Pixel التي تم إرجاعها بواسطة CFDatagetByteptr.

هذا حل القضية بالنسبة لي:

#if TARGET_IPHONE_SIMULATOR
        UInt8 red =   data[offset];
        UInt8 green = data[offset + 1];
        UInt8 blue =  data[offset + 2];
#else
        //on device
        UInt8 blue =  data[offset];       //notice red and blue are swapped
        UInt8 green = data[offset + 1];
        UInt8 red =   data[offset + 2];
#endif

لست متأكدا مما إذا كان هذا سيصلح مشكلتك، لكن رمز سوء التصرف يبدو قريبا من ما بدا الأمر قبل إصلاحه.

آخر شيء آخر: أعتقد أن المحاكاة سيتيح لك الوصول إلى المخزن المؤقت بكسل الخاص بك data[] حتى بعد CFRelease(bitmapData) يسمى. على الجهاز هذا ليس القضية في تجربتي. لا ينبغي أن يتأثر الكود الخاص بك، ولكن في حالة يساعد هذا شخص آخر اعتقدت أنني سأذكره.

نصائح أخرى

يمكنك تجربة النهج البديل التالي:

  • إنشاء cgbitmapcontext.
  • ارسم الصورة في السياق
  • استدعاء cgbitmapcontextgetdata في السياق للحصول على البيانات الأساسية
  • قم بعمل تعويضك في البيانات الأولية (بناء على كيفية إنشاء سياق الصورة النقطية)
  • استخراج القيمة

هذا النهج يعمل بالنسبة لي على المحاكاة والجهاز.

يبدو ذلك في الكود المنشور في الأسئلة الأصلية بدلا من:

NSUInteger x = (NSUInteger)floor(point.x);
NSUInteger y = height - (NSUInteger)floor(point.y);

يجب أن يكون:

NSUInteger x = (NSUInteger)floor(point.x);
NSUInteger y = (NSUInteger)floor(point.y);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top