2012-10-26 8 views
8

Sto lavorando in un'app in cui ho bisogno di disegnare l'istogramma di qualsiasi immagine inserita. Posso disegnare con successo l'istogramma ma non è così nitido come in PREVIEW in Mac OS.L'istogramma del disegno richiede più precisione in iPhone

Come codice è troppo grande, ho caricato a GitHub Click here to Download

i valori RGB vengono letti in

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

I valori memorizzati nelle variabili c matrice, Fltr, fltG, fltB.

ho una classe ClsDrawPoint ha membri

@property CGFloat x; 
@property CGFloat y; 

Poi preparato un array contenente oggetti con indice ClsDrawPoint Fltr [s '] come valore X e il valore di tale indice come valore Y.

matrice viene preparata e grafico viene aspirata

-(void)makeArrays 

metodo

Si può visualizzare il risultato

enter image description here

Attualmente non è così preciso come in ANTEPRIMA in mac per la stessa immagine. Puoi aprire un'immagine nell'app ANTEPRIMA in Mac e in Strumenti> RegolaColor, sarai in grado di vedere l'istogramma di quell'immagine. Penso che se il mio grafico è accrate, sarà più nitido. Si prega di controllare il mio codice e suggerirmi se lo trovate comunque per renderlo più accurato.

risposta

4

Ho estratto il campione da Github e ho scoperto che il tuo metodo drawRect: in ClsDraw sta disegnando linee larghe un pixel. Gli tratti sono centrati sulla linea e con una larghezza di 1, la traccia viene divisa in mezzo-pixel che introduce l'anti-aliasing.

Ho spostato gli offset orizzontali di mezzo pixel e il rendering appare nitido. Non ho sbagliato con gli offset verticali, ma per renderli nitidi avresti bisogno di arrotondarli e quindi spostarli anche in offset a mezzo pixel. Ho fatto solo la seguente modifica:

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

Avviso il nuovo OFFSET_X e l'introduzione di adjustedPoint.

Si potrebbe anche considerare l'utilizzo di un CGPoint farcito in un NSValue istanza per i tuoi punti invece della classe personalizzata ClsDrawPoint, a meno che non si prevede di aggiungere alcuni comportamenti o in ulteriore. Maggiori dettagli disponibili here.

+1

grazie per NSValue, davvero non lo sapevo. Il grafico è accurato ma non è così preciso come è nell'anteprima. Puoi suggerirmi di più ??? – HarshIT

+1

ho provato sodo ma non ho potuto ottenere altro modo .... grazie. questi voti sono per la tua mano ... – HarshIT

Problemi correlati