UIImage (कोको टच) या CGImage (कोर ग्राफिक्स) से पिक्सेल डेटा कैसे प्राप्त करें?


200

मेरे पास एक UIImage (कोको टच) है। उस से, मुझे एक सीजीआईएमएजी या कुछ और जो आप उपलब्ध हैं, प्राप्त करने में खुशी हो रही है। मैं यह फ़ंक्शन लिखना चाहता हूं:

- (int)getRGBAFromImage:(UIImage *)image atX:(int)xx andY:(int)yy {
  // [...]
  // What do I want to read about to help
  // me fill in this bit, here?
  // [...]

  int result = (red << 24) | (green << 16) | (blue << 8) | alpha;
  return result;
}

जवाबों:


249

FYI करें, मैंने अपने मूल रूपरेखा के साथ केरेमेक के उत्तर को जोड़ा, टाइप-अप को साफ किया, इसे रंगों की एक सरणी वापस करने के लिए सामान्यीकृत किया और पूरी बात संकलित करने के लिए मिला। यहाँ परिणाम है:

+ (NSArray*)getRGBAsFromImage:(UIImage*)image atX:(int)x andY:(int)y count:(int)count
{
    NSMutableArray *result = [NSMutableArray arrayWithCapacity:count];

    // First get the image into your data buffer
    CGImageRef imageRef = [image CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                    bitsPerComponent, bytesPerRow, colorSpace,
                    kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);

    // Now your rawData contains the image data in the RGBA8888 pixel format.
    NSUInteger byteIndex = (bytesPerRow * y) + x * bytesPerPixel;
    for (int i = 0 ; i < count ; ++i)
    {
        CGFloat alpha = ((CGFloat) rawData[byteIndex + 3] ) / 255.0f;
        CGFloat red   = ((CGFloat) rawData[byteIndex]     ) / alpha;
        CGFloat green = ((CGFloat) rawData[byteIndex + 1] ) / alpha;
        CGFloat blue  = ((CGFloat) rawData[byteIndex + 2] ) / alpha;
        byteIndex += bytesPerPixel;

        UIColor *acolor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
        [result addObject:acolor];
    }

  free(rawData);

  return result;
}

4
रंग unmultiply भूलना मत। इसके अलावा, उन गुणन 1 से कुछ भी नहीं करते हैं।
पीटर होसी

2
भले ही वह सही हो। जब गिनती एक बड़ी संख्या होती है (जैसे कि छवि की एक पंक्ति की लंबाई या संपूर्ण छवि का आकार!) तो इस विधि का प्रदर्शन अच्छा नहीं है क्योंकि बहुत अधिक यूकोकल ऑब्जेक्ट वास्तव में भारी हैं। वास्तविक जीवन में जब मुझे एक पिक्सेल की आवश्यकता होती है तो UIColor ठीक है, (UIColors का एक NSArray मेरे लिए बहुत अधिक है)। और जब आपको रंगों के गुच्छा की आवश्यकता होगी तो मैं UIColors का उपयोग नहीं करूंगा क्योंकि मैं शायद OpenGL का उपयोग कर रहा हूं, आदि। मेरी राय में इस पद्धति का कोई वास्तविक जीवन उपयोग नहीं है, लेकिन शैक्षिक उद्देश्यों के लिए बहुत अच्छा है।
nacho4d

4
जिस तरह से एक पिक्सेल को पढ़ने के लिए बहुत बड़ा बोझिल मॉलोक।
ragnarius

46
MALLOC के CALLOC INSTEAD का उपयोग करें !!!! मैं इस कोड का उपयोग कर परीक्षण कर रहा था कि क्या कुछ पिक्सेल पारदर्शी थे और मुझे बैकॉग की जानकारी मिल रही थी, जहाँ पिक्सल पारदर्शी होना था क्योंकि मेमोरी पहले क्लियर नहीं हुई थी। मॉलॉक के बजाय कॉलोक (चौड़ाई * ऊंचाई, 4) का उपयोग कर चाल चली। बाकी कोड बहुत अच्छा है, धन्यवाद!
डोनाला

5
यह भी खूब रही। धन्यवाद। उपयोग पर ध्यान दें: x और y आरजीबी से प्राप्त करने के लिए छवि के भीतर निर्देशांक हैं और 'गिनती' उस बिंदु से पिक्सेल की संख्या है, जो बाएं से दाएं जा रही है, फिर पंक्ति से पंक्ति। उदाहरण उपयोग: संपूर्ण छवि के getRGBAsFromImage:image atX:0 andY:0 count:image.size.width*image.size.height लिए RGBAs प्राप्त करने के लिए : किसी छवि की अंतिम पंक्ति के लिए RGBAs प्राप्त करने के लिए: getRGBAsFromImage:image atX:0 andY:image.size.height-1 count:image.size.width
Harris

49

इसे करने का एक तरीका यह है कि छवि को एक बिटमैप संदर्भ में खींचा जाए जो किसी दिए गए कलरस्पेस के लिए दिए गए बफर द्वारा समर्थित है (इस मामले में यह RGB है): (ध्यान दें कि यह छवि डेटा को उस बफर में कॉपी कर देगा, इसलिए आप ऐसा करते हैं हर बार जब आप पिक्सेल मान प्राप्त करना चाहते हैं, तो इस ऑपरेशन को करने के बजाय इसे कैश करना चाहते हैं)

नमूने के रूप में नीचे देखें:

// First get the image into your data buffer
CGImageRef image = [myUIImage CGImage];
NSUInteger width = CGImageGetWidth(image);
NSUInteger height = CGImageGetHeight(image);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = malloc(height * width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);

CGContextDrawImage(context, CGRectMake(0, 0, width, height));
CGContextRelease(context);

// Now your rawData contains the image data in the RGBA8888 pixel format.
int byteIndex = (bytesPerRow * yy) + xx * bytesPerPixel;
red = rawData[byteIndex];
green = rawData[byteIndex + 1];
blue = rawData[byteIndex + 2];
alpha = rawData[byteIndex + 3];

मैंने अपने ऐप में कुछ ऐसा ही किया। एक मनमाने ढंग से पिक्सेल निकालने के लिए, आप बस 1x1 बिटमैप में एक ज्ञात बिटमैप प्रारूप के साथ आकर्षित करते हैं, CGBitmapContext की उत्पत्ति को उचित रूप से समायोजित करते हैं।
मार्क बेसे

5
यह स्मृति लीक करती है। रिलीज कच्चेडटा: मुफ्त (रॉडाटा);
एडम वेट

5
CGContextDrawImageतीन तर्कों की आवश्यकता है और केवल दो से ऊपर दिए गए हैं ... मुझे लगता है कि यह होना चाहिएCGContextDrawImage(context, CGRectMake(0, 0, width, height), image)
user1135469

25

Apple का तकनीकी प्रश्नोत्तर AA1509 निम्नलिखित सरल दृष्टिकोण दिखाता है:

CFDataRef CopyImagePixels(CGImageRef inImage)
{
    return CGDataProviderCopyData(CGImageGetDataProvider(inImage));
}

CFDataGetBytePtrवास्तविक बाइट्स (और CGImageGet*कैसे व्याख्या करने के लिए समझने के लिए विभिन्न तरीकों) को प्राप्त करने के लिए उपयोग करें ।


10
यह एक महान दृष्टिकोण नहीं है क्योंकि पिक्सेल प्रारूप प्रति छवि बहुत भिन्न होता है। कई चीजें हैं जो बदल सकती हैं, जिसमें 1. छवि का अभिविन्यास 2. अल्फा घटक का प्रारूप और 3. आरजीबी का बाइट क्रम। मैंने व्यक्तिगत रूप से कुछ समय बिताया है कि यह कैसे करना है पर Apple के डॉक्स को डिकोड करने की कोशिश कर रहा हूं, लेकिन मुझे यकीन नहीं है कि यह इसके लायक है। यदि आप चाहते हैं कि यह तेजी से किया जाए, तो बस केरेमेक का समाधान।
टायलर

1
यह तरीका हमेशा मुझे बीजीआर प्रारूप देता है, भले ही मैं छवि को सहेजता हूं (मेरे ऐप के भीतर कलरस्पेस आरजीबीए में)
सौम्यजीत

1
@Soumyaljit यह उस प्रारूप में डेटा की प्रतिलिपि बनाने जा रहा है जिसे CGImageRef डेटा मूल रूप से संग्रहीत किया गया था। ज्यादातर मामलों में यह बीजीआरए होने वाला है, लेकिन वाईयूवी भी हो सकता है।
कैमरन लोवेल पामर

18

विश्वास नहीं हो रहा था कि यहाँ एक भी सही उत्तर नहीं है। पॉइंटर्स आवंटित करने की आवश्यकता नहीं है, और गैर-मान्यता प्राप्त मूल्यों को अभी भी सामान्यीकृत करने की आवश्यकता है। पीछा करने के लिए कटौती करने के लिए, यहाँ स्विफ्ट 4 का सही संस्करण है । UIImageकेवल उपयोग के लिए .cgImage

extension CGImage {
    func colors(at: [CGPoint]) -> [UIColor]? {
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        let bytesPerPixel = 4
        let bytesPerRow = bytesPerPixel * width
        let bitsPerComponent = 8
        let bitmapInfo: UInt32 = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Big.rawValue

        guard let context = CGContext(data: nil, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo),
            let ptr = context.data?.assumingMemoryBound(to: UInt8.self) else {
            return nil
        }

        context.draw(self, in: CGRect(x: 0, y: 0, width: width, height: height))

        return at.map { p in
            let i = bytesPerRow * Int(p.y) + bytesPerPixel * Int(p.x)

            let a = CGFloat(ptr[i + 3]) / 255.0
            let r = (CGFloat(ptr[i]) / a) / 255.0
            let g = (CGFloat(ptr[i + 1]) / a) / 255.0
            let b = (CGFloat(ptr[i + 2]) / a) / 255.0

            return UIColor(red: r, green: g, blue: b, alpha: a)
        }
    }
}

आपको चित्र को पहले बफर में बदलने / बदलने का कारण यह है क्योंकि छवियों के कई अलग-अलग प्रारूप हो सकते हैं। इस चरण को एक सुसंगत प्रारूप में परिवर्तित करने के लिए आवश्यक है जिसे आप पढ़ सकते हैं।


मैं अपनी छवि के लिए इस एक्सटेंशन का उपयोग कैसे कर सकता हूं? LetObj = UIImage (नाम: "greencolorImg.png")
सागर सुकोडे

let imageObj = UIImage(named:"greencolorImg.png"); imageObj.cgImage?.colors(at: [pt1, pt2])
एरिक एगर

ध्यान रखें कि pt1और pt2कर रहे हैं CGPointचर।
अनीस्व

मेरा दिन बचा लिया :)
Dari

1
@ErikAigner यह काम करेगा अगर मैं एक छवि के प्रत्येक पिक्सेल का रंग प्राप्त करना चाहता था? प्रदर्शन लागत क्या है?
अमीट धस

9

यहाँ एक SO थ्रेड है जहाँ @Matt छवि को विस्थापित करके केवल वांछित पिक्सेल को 1x1 संदर्भ में प्रस्तुत करता है ताकि वांछित पिक्सेल संदर्भ में एक पिक्सेल के साथ संरेखित हो जाए।


9
NSString * path = [[NSBundle mainBundle] pathForResource:@"filename" ofType:@"jpg"];
UIImage * img = [[UIImage alloc]initWithContentsOfFile:path];
CGImageRef image = [img CGImage];
CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(image));
const unsigned char * buffer =  CFDataGetBytePtr(data);

मैंने इसे पोस्ट किया है और इसने मेरे लिए काम किया है, लेकिन बफर से वापस एक यूआईएमएजेज आई कैंट में जाने का अभी तक कोई अनुमान नहीं है?
निदाल फखौरी

8

UIImage एक रैपर है बाइट्स CGImage या CIImage हैं

UIImage पर Apple संदर्भ के अनुसार ऑब्जेक्ट अपरिवर्तनीय है और आपको बैकिंग बाइट्स तक कोई पहुंच नहीं है। हालांकि यह सच है कि आप CGImage डेटा अगर आप आबादी तक पहुँच सकते हैं UIImageके साथ एक CGImage(स्पष्ट या परोक्ष), यह वापस आ जाएगी NULL, तो UIImageएक के द्वारा समर्थित है CIImageउपाध्यक्ष प्रतिकूल और।

छवि ऑब्जेक्ट्स उनके अंतर्निहित छवि डेटा तक सीधी पहुंच प्रदान नहीं करते हैं। हालाँकि, आप अपने ऐप में उपयोग के लिए अन्य स्वरूपों में छवि डेटा पुनः प्राप्त कर सकते हैं। विशेष रूप से, आप छवि के संस्करणों को पुनर्प्राप्त करने के लिए cgImage और ciImage गुणों का उपयोग कर सकते हैं जो क्रमशः कोर ग्राफिक्स और कोर छवि के साथ संगत हैं। आप UIImagePNGRepresentation ( :) और UIImageJPEGRepresentation ( : _ :) फ़ंक्शन का उपयोग करके NSData ऑब्जेक्ट को PNG या JPEG प्रारूप में छवि डेटा युक्त ऑब्जेक्ट उत्पन्न कर सकते हैं।

इस मुद्दे के आसपास होने के आम ट्रिक

जैसा कि कहा गया है कि आपके विकल्प हैं

  • UIImagePNGRepresentation या JPEG
  • यह निर्धारित करें कि छवि में CGImage या CIImage बैकिंग डेटा है और इसे वहां प्राप्त करें

यदि आप ऐसा आउटपुट चाहते हैं जो ARGB, PNG या JPEG डेटा नहीं है, तो इनमें से कोई भी विशेष ट्रिक नहीं है और डेटा CIImage द्वारा पहले से ही समर्थित नहीं है।

मेरी सिफारिश, CIImage की कोशिश करो

अपनी परियोजना को विकसित करते समय, यह आपके लिए UIImage से पूरी तरह से बचने और कुछ और लेने के लिए अधिक समझ में आ सकता है। UIImage, Obj-C इमेज रैपर के रूप में, अक्सर CGImage द्वारा उस बिंदु पर समर्थित होता है, जहाँ हम इसे ले जाते हैं। CIImage एक बेहतर आवरण प्रारूप है जिसमें आप CIContext का उपयोग कर सकते हैं का जिस प्रारूप की इच्छा रखते हैं उसे यह जानने की आवश्यकता के बिना कि यह कैसे बनाया गया था। आपके मामले में, बिटमैप प्राप्त करना कॉलिंग का विषय होगा

- रेंडर: बिटमैप: पंक्तिबद्ध: सीमा: प्रारूप: रंगक्षेत्र:

एक अतिरिक्त बोनस के रूप में आप छवि पर फिल्टर का पीछा करके छवि के लिए अच्छा हेरफेर करना शुरू कर सकते हैं। यह बहुत सारे मुद्दों को हल करता है जहां छवि उलटी है या इसे घुमाया / बढ़ाया जा सकता है आदि।


6

Olie और Algal के उत्तर पर बिल्डिंग, यहाँ Swift 3 के लिए एक अद्यतन उत्तर है

public func getRGBAs(fromImage image: UIImage, x: Int, y: Int, count: Int) -> [UIColor] {

var result = [UIColor]()

// First get the image into your data buffer
guard let cgImage = image.cgImage else {
    print("CGContext creation failed")
    return []
}

let width = cgImage.width
let height = cgImage.height
let colorSpace = CGColorSpaceCreateDeviceRGB()
let rawdata = calloc(height*width*4, MemoryLayout<CUnsignedChar>.size)
let bytesPerPixel = 4
let bytesPerRow = bytesPerPixel * width
let bitsPerComponent = 8
let bitmapInfo: UInt32 = CGImageAlphaInfo.premultipliedLast.rawValue | CGBitmapInfo.byteOrder32Big.rawValue

guard let context = CGContext(data: rawdata, width: width, height: height, bitsPerComponent: bitsPerComponent, bytesPerRow: bytesPerRow, space: colorSpace, bitmapInfo: bitmapInfo) else {
    print("CGContext creation failed")
    return result
}

context.draw(cgImage, in: CGRect(x: 0, y: 0, width: width, height: height))

// Now your rawData contains the image data in the RGBA8888 pixel format.
var byteIndex = bytesPerRow * y + bytesPerPixel * x

for _ in 0..<count {
    let alpha = CGFloat(rawdata!.load(fromByteOffset: byteIndex + 3, as: UInt8.self)) / 255.0
    let red = CGFloat(rawdata!.load(fromByteOffset: byteIndex, as: UInt8.self)) / alpha
    let green = CGFloat(rawdata!.load(fromByteOffset: byteIndex + 1, as: UInt8.self)) / alpha
    let blue = CGFloat(rawdata!.load(fromByteOffset: byteIndex + 2, as: UInt8.self)) / alpha
    byteIndex += bytesPerPixel

    let aColor = UIColor(red: red, green: green, blue: blue, alpha: alpha)
    result.append(aColor)
}

free(rawdata)

return result
}


3

स्विफ्ट 5 संस्करण

यहां दिए गए उत्तर या तो पुराने या गलत हैं क्योंकि वे निम्नलिखित बातों पर ध्यान नहीं देते हैं:

  1. छवि का पिक्सेल आकार उसके बिंदु आकार से भिन्न हो सकता है जिसे image.size.width/ द्वारा लौटाया जाता है /image.size.height
  2. छवि में पिक्सेल घटकों द्वारा उपयोग किए जाने वाले विभिन्न लेआउट हो सकते हैं, जैसे बीजीआरए, एबीजीआर, एआरजीबी आदि या बीजीआर और आरजीबी जैसे अल्फा घटक बिल्कुल नहीं हो सकते हैं। उदाहरण के लिए, UIView.drawHierarchy(in:afterScreenUpdates:)विधि बीजीआरए छवियों का उत्पादन कर सकती है।
  3. रंग घटकों को छवि में सभी पिक्सेल के लिए अल्फा द्वारा प्रीमियर किया जा सकता है और मूल रंग को पुनर्स्थापित करने के लिए अल्फा द्वारा विभाजित करने की आवश्यकता है।
  4. द्वारा उपयोग किए जाने वाले मेमोरी ऑप्टिमाइज़ेशन के लिए CGImage, बाइट्स में पिक्सेल पंक्ति का आकार पिक्सेल चौड़ाई 4 से मात्र गुणा से अधिक हो सकता है।

नीचे दिए गए कोड को UIColorऐसे सभी विशेष मामलों के लिए पिक्सेल प्राप्त करने के लिए एक सार्वभौमिक स्विफ्ट 5 समाधान प्रदान करना है । कोड प्रयोज्य और स्पष्टता के लिए अनुकूलित है, प्रदर्शन के लिए नहीं

public extension UIImage {

    var pixelWidth: Int {
        return cgImage?.width ?? 0
    }

    var pixelHeight: Int {
        return cgImage?.height ?? 0
    }

    func pixelColor(x: Int, y: Int) -> UIColor {
        assert(
            0..<pixelWidth ~= x && 0..<pixelHeight ~= y,
            "Pixel coordinates are out of bounds")

        guard
            let cgImage = cgImage,
            let data = cgImage.dataProvider?.data,
            let dataPtr = CFDataGetBytePtr(data),
            let colorSpaceModel = cgImage.colorSpace?.model,
            let componentLayout = cgImage.bitmapInfo.componentLayout
        else {
            assertionFailure("Could not get a pixel of an image")
            return .clear
        }

        assert(
            colorSpaceModel == .rgb,
            "The only supported color space model is RGB")
        assert(
            cgImage.bitsPerPixel == 32 || cgImage.bitsPerPixel == 24,
            "A pixel is expected to be either 4 or 3 bytes in size")

        let bytesPerRow = cgImage.bytesPerRow
        let bytesPerPixel = cgImage.bitsPerPixel/8
        let pixelOffset = y*bytesPerRow + x*bytesPerPixel

        if componentLayout.count == 4 {
            let components = (
                dataPtr[pixelOffset + 0],
                dataPtr[pixelOffset + 1],
                dataPtr[pixelOffset + 2],
                dataPtr[pixelOffset + 3]
            )

            var alpha: UInt8 = 0
            var red: UInt8 = 0
            var green: UInt8 = 0
            var blue: UInt8 = 0

            switch componentLayout {
            case .bgra:
                alpha = components.3
                red = components.2
                green = components.1
                blue = components.0
            case .abgr:
                alpha = components.0
                red = components.3
                green = components.2
                blue = components.1
            case .argb:
                alpha = components.0
                red = components.1
                green = components.2
                blue = components.3
            case .rgba:
                alpha = components.3
                red = components.0
                green = components.1
                blue = components.2
            default:
                return .clear
            }

            // If chroma components are premultiplied by alpha and the alpha is `0`,
            // keep the chroma components to their current values.
            if cgImage.bitmapInfo.chromaIsPremultipliedByAlpha && alpha != 0 {
                let invUnitAlpha = 255/CGFloat(alpha)
                red = UInt8((CGFloat(red)*invUnitAlpha).rounded())
                green = UInt8((CGFloat(green)*invUnitAlpha).rounded())
                blue = UInt8((CGFloat(blue)*invUnitAlpha).rounded())
            }

            return .init(red: red, green: green, blue: blue, alpha: alpha)

        } else if componentLayout.count == 3 {
            let components = (
                dataPtr[pixelOffset + 0],
                dataPtr[pixelOffset + 1],
                dataPtr[pixelOffset + 2]
            )

            var red: UInt8 = 0
            var green: UInt8 = 0
            var blue: UInt8 = 0

            switch componentLayout {
            case .bgr:
                red = components.2
                green = components.1
                blue = components.0
            case .rgb:
                red = components.0
                green = components.1
                blue = components.2
            default:
                return .clear
            }

            return .init(red: red, green: green, blue: blue, alpha: UInt8(255))

        } else {
            assertionFailure("Unsupported number of pixel components")
            return .clear
        }
    }

}

public extension UIColor {

    convenience init(red: UInt8, green: UInt8, blue: UInt8, alpha: UInt8) {
        self.init(
            red: CGFloat(red)/255,
            green: CGFloat(green)/255,
            blue: CGFloat(blue)/255,
            alpha: CGFloat(alpha)/255)
    }

}

public extension CGBitmapInfo {

    enum ComponentLayout {

        case bgra
        case abgr
        case argb
        case rgba
        case bgr
        case rgb

        var count: Int {
            switch self {
            case .bgr, .rgb: return 3
            default: return 4
            }
        }

    }

    var componentLayout: ComponentLayout? {
        guard let alphaInfo = CGImageAlphaInfo(rawValue: rawValue & Self.alphaInfoMask.rawValue) else { return nil }
        let isLittleEndian = contains(.byteOrder32Little)

        if alphaInfo == .none {
            return isLittleEndian ? .bgr : .rgb
        }
        let alphaIsFirst = alphaInfo == .premultipliedFirst || alphaInfo == .first || alphaInfo == .noneSkipFirst

        if isLittleEndian {
            return alphaIsFirst ? .bgra : .abgr
        } else {
            return alphaIsFirst ? .argb : .rgba
        }
    }

    var chromaIsPremultipliedByAlpha: Bool {
        let alphaInfo = CGImageAlphaInfo(rawValue: rawValue & Self.alphaInfoMask.rawValue)
        return alphaInfo == .premultipliedFirst || alphaInfo == .premultipliedLast
    }

}

अभिविन्यास में परिवर्तन के बारे में क्या? क्या आपको UIImage.Orientation की जाँच करने की आवश्यकता नहीं है?
20

इसके अलावा, अपने componentLayout, मामले की याद आ रही है जब वहाँ केवल अल्फा है .alphaOnly
21

@endavid "अल्फा केवल" समर्थित नहीं है (एक बहुत ही दुर्लभ मामला होने के लिए)। छवि अभिविन्यास इस कोड के दायरे से बाहर है, लेकिन इसके उन्मुखीकरण को सामान्य करने के तरीके के बारे में काफी संसाधन हैं UIImage, जो कि आप अपने पिक्सेल रंगों को पढ़ना शुरू करने से पहले क्या करेंगे।
डेसमंड ह्यूम

2

अलग-अलग उत्तरों के आधार पर लेकिन मुख्य रूप से यह इस बात के लिए काम करता है कि मुझे क्या चाहिए:

UIImage *image1 = ...; // The image from where you want a pixel data
int pixelX = ...; // The X coordinate of the pixel you want to retrieve
int pixelY = ...; // The Y coordinate of the pixel you want to retrieve

uint32_t pixel1; // Where the pixel data is to be stored
CGContextRef context1 = CGBitmapContextCreate(&pixel1, 1, 1, 8, 4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaNoneSkipFirst);
CGContextDrawImage(context1, CGRectMake(-pixelX, -pixelY, CGImageGetWidth(image1.CGImage), CGImageGetHeight(image1.CGImage)), image1.CGImage);
CGContextRelease(context1);

इस पंक्तियों के परिणामस्वरूप, आपके पास AARRGGBB प्रारूप में एक पिक्सेल होगा जिसमें अल्फा हमेशा 4 बाइट अहस्ताक्षरित पूर्णांक में FF पर सेट होता है pixel1


1

स्विफ्ट 5 में एक UIImage के कच्चे RGB मानों को एक्सेस करने के लिए अंतर्निहित CGImage और उसके डेटा का उपयोग करें:

import UIKit

let image = UIImage(named: "example.png")!

guard let cgImage = image.cgImage,
    let data = cgImage.dataProvider?.data,
    let bytes = CFDataGetBytePtr(data) else {
    fatalError("Couldn't access image data")
}
assert(cgImage.colorSpace?.model == .rgb)

let bytesPerPixel = cgImage.bitsPerPixel / cgImage.bitsPerComponent
for y in 0 ..< cgImage.height {
    for x in 0 ..< cgImage.width {
        let offset = (y * cgImage.bytesPerRow) + (x * bytesPerPixel)
        let components = (r: bytes[offset], g: bytes[offset + 1], b: bytes[offset + 2])
        print("[x:\(x), y:\(y)] \(components)")
    }
    print("---")
}

https://www.ralfebert.de/ios/examples/image-processing/uiimage-raw-pixels/

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.