2012-10-26 59 views
8

我在一個應用程序中工作,我需要繪製任何輸入圖像的直方圖。我可以成功繪製直方圖,但不像它在Mac OS中的PREVIEW中那樣清晰。繪圖直方圖在iPhone中需要更高的準確度

作爲代碼太大,我已經上傳到的GitHub Click here to Download

的RGB值被讀入

-(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); 
} 

予C中的數組變量,FLTR,fltG,FLTB存儲的值。

我有一個類ClsDrawPoint它具有構件

@property CGFloat x; 
@property CGFloat y; 

然後製備含有具有FLTR的[]索引ClsDrawPoint的物體作爲該索引爲Y值的X值和值的數組。

陣列製備和圖形在

-(void)makeArrays 

方法繪製

您可能看到結果

enter image description here

目前其不那麼精確,因爲它是在PREVIEW在mac爲相同的圖像。您可以在Mac的PREVIEW應用程序中打開圖像,然後在工具>調整顏色中,您將能夠看到該圖像的直方圖。 我認爲如果我的圖表出現錯誤,它會更清晰。請檢查我的代碼,並建議我,如果你發現無論如何,使其更加準確。

回答

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塞進一個NSValue實例爲您的積分,而不是你的自定義類ClsDrawPoint,除非你打算添加一些額外的行爲或屬性。更多詳細信息可用here

+1

感謝NSValue,我真的不知道這一點。圖表是準確的,但仍然不如預覽中那麼準確..你能給我更多的建議嗎? – HarshIT

+1

我努力嘗試,但無法得到更多的方式....謝謝。這些贊成票是爲你的手工作... – HarshIT