I am working in an app in which I need to draw Histogram of any inputed image. I can draw Histogram successfully but its not so sharp as its in PREVIEW in Mac OS.
As code is too large ,I have uploaded it to GitHub Click here to Download
The RGB Values are read 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 stored values in c array variables , fltR,fltG,fltB.
I have a class ClsDrawPoint it has members
@property CGFloat x;
@property CGFloat y;
Then prepared an array containing objects of ClsDrawPoint having fltR[]'s index as X value and value for that index as Y value .
array is prepared and graph is drawn in
-(void)makeArrays
method
You may see the result
Currently its not so accurate as it is in PREVIEW in mac for the same image. You can open an image in PREVIEW app in Mac and in Tools>AdjustColor , you will be able to see the Histogram of that image. I think if my graph is accrate , it will be sharper. Kindly check my code and suggest me if you find anyway to make it more accurate.
I pulled your sample down from Github and found that your drawRect:
method in ClsDraw
is drawing lines that are one pixel wide. Strokes are centered on the line, and with a width of 1, the stroke is split into half-pixels which introduces anti-aliasing.
I moved your horizontal offsets by a half-pixel and rendering looks sharp. I didn't mess with vertical offsets, but to make them sharp you would need to round them and then move them to a half-pixel offset as well. I only made the following change:
#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);
}
}
}
Notice the new OFFSET_X
and the introduction of adjustedPoint
.
You might also consider using a CGPoint
stuffed into an NSValue
instance for your points instead of your custom class ClsDrawPoint
, unless you plan to add some additional behavior or properties. More details available here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With