2012-10-26 3 views
8

में अधिक सटीकता की आवश्यकता है मैं एक ऐप में काम कर रहा हूं जिसमें मुझे किसी भी इनपुट छवि के हिस्टोग्राम को आकर्षित करने की आवश्यकता है। मैं हिस्टोग्राम सफलतापूर्वक आकर्षित कर सकता हूं लेकिन यह मैक ओएस में पूर्वावलोकन में उतना तेज़ नहीं है।ड्राइंग हिस्टोग्राम को आईफोन

कोड बहुत बड़ा है के रूप में, मैं यह GitHub Click here to Download

पर अपलोड की गई आरजीबी मान

-(void)readImage:(UIImage*)image 
{ 
    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); 

    for (int yy=0;yy<height; yy++) 
    { 
     for (int xx=0; xx<width; xx++) 
     { 
      // Now your rawData contains the image data in the RGBA8888 pixel format. 
      int byteIndex = (bytesPerRow * yy) + xx * bytesPerPixel; 
      for (int ii = 0 ; ii < 1 ; ++ii) 
      { 
       CGFloat red = (rawData[byteIndex]  * 1.0) ; 
       CGFloat green = (rawData[byteIndex + 1] * 1.0) ; 
       CGFloat blue = (rawData[byteIndex + 2] * 1.0) ; 
       // CGFloat alpha = (rawData[byteIndex + 3] * 1.0)/255.0; 
       byteIndex += 4; 

       // TYPE CASTING ABOVE FLOAT VALUES TO THAT THEY CAN BE MATCHED WITH ARRAY'S INDEX. 

       int redValue = (int)red; 
       int greenValue = (int)green; 
       int blueValue = (int)blue; 


       // THESE COUNTERS COUNT " TOTAL NUMBER OF PIXELS " FOR THAT Red , Green or Blue Value IN ENTIRE IMAGE. 

       fltR[redValue]++; 
       fltG[greenValue]++; 
       fltB[blueValue]++;     
      } 
     } 
    } 
    [self makeArrays]; 
    free(rawData); 
} 

ग सरणी चर, FLTR, fltG, fltB में मैं संग्रहीत मूल्यों में पढ़ रहे हैं।

मैं ClsDrawPoint यह सदस्यों

@property CGFloat x; 
@property CGFloat y; 

फिर एक्स मूल्य और वाई मूल्य के रूप में है कि सूचकांक के लिए मूल्य के रूप में ClsDrawPoint होने FLTR [] के सूचकांक की वस्तुओं से युक्त एक सरणी तैयार है एक वर्ग है।

सरणी तैयार किया जाता है और ग्राफ में

-(void)makeArrays 

विधि तैयार की है

आप परिणाम

enter image description here

वर्तमान में इसकी इतनी सटीक नहीं देख सकते हैं के रूप में यह में पूर्वावलोकन में है एक ही छवि के लिए मैक। आप मैक में PREVIEW ऐप में और टूल> एडजस्टकॉलर में एक छवि खोल सकते हैं, आप उस छवि के हिस्टोग्राम को देख पाएंगे। मुझे लगता है कि अगर मेरा ग्राफ accrate है, तो यह तेज होगा। कृपया मेरे कोड की जांच करें और मुझे सुझाव दें कि क्या आपको इसे और अधिक सटीक बनाने के लिए वैसे भी मिलते हैं।

उत्तर

4

मैं Github से नीचे अपने नमूना खींच लिया और पाया कि ClsDraw में अपने drawRect: विधि लाइनों है कि एक पिक्सेल चौड़ा कर रहे हैं आ रहा है। स्ट्रोक लाइन पर केंद्रित होते हैं, और 1 की चौड़ाई के साथ, स्ट्रोक को अर्ध-पिक्सल में विभाजित किया जाता है जो एंटी-एलियासिंग पेश करता है।

मैंने आपके क्षैतिज ऑफ़सेट को आधा पिक्सेल तक ले जाया और प्रतिपादन तेज दिखता है। मैंने ऊर्ध्वाधर ऑफसेट के साथ गड़बड़ नहीं की, लेकिन उन्हें तेज बनाने के लिए आपको उन्हें गोल करने की आवश्यकता होगी और फिर उन्हें आधे पिक्सेल ऑफसेट पर ले जाना होगा।

#define OFFSET_X 0.5 

- (void)drawRect:(CGRect)rect 
{ 
    CGContextRef ctx = UIGraphicsGetCurrentContext(); 
    if ([arrPoints count] > 0) 
    { 
    CGContextSetLineWidth(ctx, 1); 
    CGContextSetStrokeColorWithColor(ctx, graphColor.CGColor); 
    CGContextSetAlpha(ctx, 0.8); 
    ClsDrawPoint *objPoint; 
    CGContextBeginPath(ctx); 

    for (int i = 0 ; i < [arrPoints count] ; i++) 
    { 
     objPoint = [arrPoints objectAtIndex:i]; 
     CGPoint adjustedPoint = CGPointMake(objPoint.x+OFFSET_X, objPoint.y); 
     CGContextMoveToPoint(ctx, adjustedPoint.x, 0); 
     CGContextSetLineCap(ctx, kCGLineCapRound); 
     CGContextSetLineJoin(ctx, kCGLineJoinRound); 
     CGContextAddLineToPoint(ctx, adjustedPoint.x, adjustedPoint.y); 
     CGContextMoveToPoint(ctx, adjustedPoint.x, adjustedPoint.y); 
     CGContextStrokePath(ctx); 
    } 
    } 
} 

सूचना नई OFFSET_X और adjustedPoint की शुरूआत: मैं केवल निम्न परिवर्तन किया है।

तुम भी विचार कर सकते हैं एक CGPoint अपने अंक के बजाय अपने कस्टम वर्ग ClsDrawPoint, के लिए एक NSValue उदाहरण में भरा है जब तक आप कुछ अतिरिक्त व्यवहार या गुण जोड़ने की योजना। अधिक जानकारी here उपलब्ध है।

+1

NSValue के लिए धन्यवाद, मुझे वास्तव में यह नहीं पता था। ग्राफ सटीक है लेकिन अभी भी सटीक नहीं है क्योंकि यह पूर्वावलोकन में है .. क्या आप मुझे और सुझाव दे सकते हैं ??? – HarshIT

+1

मैंने कड़ी मेहनत की लेकिन कोई और रास्ता नहीं मिला .... धन्यवाद। ये अप वोट आपके हैंडवर्क के लिए हैं ... – HarshIT