Inappropriate Images display due to overlapping in CGContext - iphone

I can't find the solution for this:
I have 2 image Views both with different image - image_1(Jeans of Person) and image_2(Shirt of person). Now when I change the RGB value individually for image_1's or image_2's each and every pixel, I get the perfect result. But whenever one of my frame from the two, slightly overlap with other after processing both of them, then the problem occurs. Please help. This is how I am processing the image.
-(UIImage *)ColorChangeProcessing :(int )redvalue greenValue:(int)greenvalue blueValue:(int)bluevalue imageUsed : (UIImage *)image
{
CGContextRef ctx;
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
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), imageRef);
CGContextRelease(context);
int byteIndex = (bytesPerRow * 0) + 0 * bytesPerPixel,RED = redvalue,GREEN=greenvalue,BLUE = bluevalue;
for (int ii = 0 ; ii < width * height ; ++ii)
{
if(rawData[byteIndex] != '/0' || rawData[byteIndex+1] != '/0' || rawData[byteIndex+2] != '/0'){
if ((((rawData[byteIndex])+RED)) > 255)
{
rawData[byteIndex] = (char)255;
}
else if((((rawData[byteIndex])+RED)) >0)
{
rawData[byteIndex] = (char) (((rawData[byteIndex] * 1.0) + RED));
}
else
{
rawData[byteIndex] = (char)0;
}
if ((((rawData[byteIndex+1])+GREEN)) > 255)
{
rawData[byteIndex+1] = (char)255;
}
else if((((rawData[byteIndex+1])+GREEN))>0)
{
rawData[byteIndex+1] = (char) (((rawData[byteIndex+1] * 1.0) + GREEN));
}
else
{
rawData[byteIndex+1] = (char)0;
}
if ((((rawData[byteIndex+2])+BLUE)) > 255)
{
rawData[byteIndex+2] = (char)255;
}
else if((((rawData[byteIndex+2])+BLUE))>0)
{
rawData[byteIndex+2] = (char) (((rawData[byteIndex+2] * 1.0) + BLUE));
}
else
{
rawData[byteIndex+2] = (char)0;
}
}
byteIndex += 4;
}
ctx = CGBitmapContextCreate(rawData,
CGImageGetWidth( imageRef ),
CGImageGetHeight( imageRef ),
8,
CGImageGetBytesPerRow( imageRef ),
CGImageGetColorSpace( imageRef ),
kCGImageAlphaPremultipliedLast );
CGImageRef NewimageRef = CGBitmapContextCreateImage (ctx);
UIImage* rawImage = [UIImage imageWithCGImage:NewimageRef];
CGContextRelease(ctx);
free(rawData);
CGImageRelease(NewimageRef);
return rawImage;
}
Now on Any button action you can set R,G,B & image values and get the processed image after that. Then just try to place those processed images frame so that some of the part of one image is covered by another. Means if you have jeans image just try to place the small portion near belt over shirt image.

Finally I came up with the solution that is I was missing to check the alpha value. So the transparent image part was the one which created problems. Thanks all.

Related

iOS grayscale/black & white

I am having an issue with some code that changes a UIImage to grayscale. It works right on iPhone/iPod, but on iPad whatever is already drawn gets all stretched and skewed in the process.
It also sometimes crashes only on iPad on the line
imageRef = CGBitmapContextCreateImage (ctx);
Here is the code:
CGContextRef ctx;
CGImageRef imageRef = [self.drawImage.image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
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), imageRef);
CGContextRelease(context);
int byteIndex = 0;
int grayScale;
for(int ii = 0 ; ii < width * height ; ++ii)
{
grayScale = (rawData[byteIndex] + rawData[byteIndex + 1] + rawData[byteIndex + 2]) / 3;
rawData[byteIndex] = (char)grayScale;
rawData[byteIndex+1] = (char)grayScale;
rawData[byteIndex+2] = (char)grayScale;
//rawData[byteIndex+3] = 255;
byteIndex += 4;
}
ctx = CGBitmapContextCreate(rawData,
CGImageGetWidth( imageRef ),
CGImageGetHeight( imageRef ),
8,
CGImageGetBytesPerRow( imageRef ),
CGImageGetColorSpace( imageRef ),
kCGImageAlphaPremultipliedLast );
imageRef = CGBitmapContextCreateImage (ctx);
UIImage* rawImage = [UIImage imageWithCGImage:imageRef];
CGContextRelease(ctx);
self.drawImage.image = rawImage;
free(rawData);
Consider leveraging the CIColorMonochrome filter available in iOS 6.
void ToMonochrome()
{
var mono = new CIColorMonochrome();
mono.Color = CIColor.FromRgb(1, 1, 1);
mono.Intensity = 1.0f;
var uiImage = new UIImage("Images/photo.jpg");
mono.Image = CIImage.FromCGImage(uiImage.CGImage);
DisplayFilterOutput(mono, ImageView);
}
static void DisplayFilterOutput(CIFilter filter, UIImageView imageView)
{
CIImage output = filter.OutputImage;
if (output == null)
return;
var context = CIContext.FromOptions(null);
var renderedImage = context.CreateCGImage(output, output.Extent);
var finalImage = new UIImage(renderedImage);
imageView.Image = finalImage;
}
Figured it out with some help elsewhere
Got rid of an extra context being used and changed the bitmap format
CGContextRef ctx;
CGImageRef imageRef = [self.drawImage.image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *rawData = malloc(height * width * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
ctx = CGBitmapContextCreate(rawData,
width,
height,
bitsPerComponent,
bytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host);
CGContextDrawImage(ctx, CGRectMake(0, 0, width, height), imageRef);
int byteIndex = 0;
int grayScale;
for(int ii = 0 ; ii < width * height ; ++ii)
{
grayScale = (rawData[byteIndex] + rawData[byteIndex + 1] + rawData[byteIndex + 2]) / 3;
rawData[byteIndex] = (char)grayScale;
rawData[byteIndex+1] = (char)grayScale;
rawData[byteIndex+2] = (char)grayScale;
//rawData[byteIndex+3] = 255;
byteIndex += 4;
}
imageRef = CGBitmapContextCreateImage(ctx);
UIImage* rawImage = [UIImage imageWithCGImage:imageRef];
CGColorSpaceRelease(colorSpace);
CGContextRelease(ctx);
self.drawImage.image = rawImage;
free(rawData);

Changing Image through pixel manipulation(iphone specific)

Similar questions must have been asked many times but this one is a tad different.
I am manipulating pixels of a image loaded in ImageView control from the photo library using the pixel values read from another image (rocks.jpg) .
Below is the code for the same:--
CGContextRef ctx;
CGImageRef imageRef = [self.workingImage CGImage];
UIImage* image2 = [UIImage imageNamed:#"rocks.jpg"];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorSpaceRef colorSpace2 = CGColorSpaceCreateDeviceRGB();
CGColorSpaceRef colorSpace3 = CGColorSpaceCreateDeviceRGB();
CGImageRef cgimage2 = image2.CGImage;
NSUInteger width2 = CGImageGetWidth(cgimage2);
NSUInteger height2 = CGImageGetHeight(cgimage2);
struct pixel* pixels = (struct pixel*) calloc(1, width * height * sizeof(struct pixel));
struct pixel* pixels2 = (struct pixel*) calloc(1, width2 * height2 * sizeof(struct pixel));
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
NSUInteger bpr2 = bytesPerPixel * width2;
//size_t bpp2 = CGImageGetBitsPerPixel(cgimage2);
NSUInteger bpc2 = 8;
CGContextRef context = CGBitmapContextCreate(pixels, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRef context2 = CGBitmapContextCreate(pixels2, width2, height2, bpc2, bpr2, colorSpace2,kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace2);
CGContextDrawImage(context2, CGRectMake(0, 0, width2, height2),cgimage2);
NSUInteger numberOfPixels = width*height;
while (numberOfPixels > 0)
{
if(pixels->g == 250)
{
pixels->r = pixels2->r;
pixels->g = pixels2->g;
pixels->b = pixels2->b;
pixels->a = pixels2->a;
// pixels->r = 0;
// pixels->g = 0;
// pixels->b = 0;
}
pixels++;
pixels2++;
numberOfPixels--;
}
ctx = CGBitmapContextCreate(pixels,
width,
height,
bitsPerComponent,
bytesPerRow,
colorSpace3,
kCGImageAlphaPremultipliedLast|kCGBitmapByteOrder32Big );
if (ctx == NULL)
{
NSLog(#"The context is null");
}
CGColorSpaceRelease(colorSpace3);
CGImageRef img2 = nil;
if (ctx != nil)
{
img2 = CGBitmapContextCreateImage (ctx);
}
//CGContextDrawImage(ctx, CGRectMake(0, 0, width, height), rawImage.CGImage );
UIImage* rawImage = [UIImage imageWithCGImage:img2];
CGContextRelease(context);
CGContextRelease(context2);
CGContextRelease(ctx);
//self.workingImage = rawImage;
//[self.imageView setImage:self.workingImage];
//[imageView setImage:rawImage];
imageView.image = rawImage;
if (pixels != NULL)
{
pixels = NULL;
free(pixels);
}
if (pixels2 != NULL)
{
pixels2 = NULL;
free(pixels2);
}
The problem is that though I can read the pixel values and also manipulate them but the end result is that the second image(rocks.jpg) gets loaded in the view instead of the manipulated image being loaded.
Can someone help me out on this.??
Thanks in advance.

Image processing Glamour filter in iphone

I want to create an app in which i want to do some image processing. So I would like to know if there is any open-source image processing library available? also I would like to create a filter like this one Glamour Filter any help regarding this would be very much appreciated. If someone already have a source code to create sepia,black and white rotate scale code than please send. Thanks
Here is the code for sepia image
-(UIImage*)makeSepiaScale:(UIImage*)image
{
CGImageRef cgImage = [image CGImage];
CGDataProviderRef provider = CGImageGetDataProvider(cgImage);
CFDataRef bitmapData = CGDataProviderCopyData(provider);
UInt8* data = (UInt8*)CFDataGetBytePtr(bitmapData);
int width = image.size.width;
int height = image.size.height;
NSInteger myDataLength = width * height * 4;
for (int i = 0; i < myDataLength; i+=4)
{
UInt8 r_pixel = data[i];
UInt8 g_pixel = data[i+1];
UInt8 b_pixel = data[i+2];
int outputRed = (r_pixel * .393) + (g_pixel *.769) + (b_pixel * .189);
int outputGreen = (r_pixel * .349) + (g_pixel *.686) + (b_pixel * .168);
int outputBlue = (r_pixel * .272) + (g_pixel *.534) + (b_pixel * .131);
if(outputRed>255)outputRed=255;
if(outputGreen>255)outputGreen=255;
if(outputBlue>255)outputBlue=255;
data[i] = outputRed;
data[i+1] = outputGreen;
data[i+2] = outputBlue;
}
CGDataProviderRef provider2 = CGDataProviderCreateWithData(NULL, data, myDataLength, NULL);
int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * width;
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef imageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider2, NULL, NO, renderingIntent);
CGColorSpaceRelease(colorSpaceRef); // YOU CAN RELEASE THIS NOW
CGDataProviderRelease(provider2); // YOU CAN RELEASE THIS NOW
CFRelease(bitmapData);
UIImage *sepiaImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef); // YOU CAN RELEASE THIS NOW
return sepiaImage;
}
Here is the code for Black & White effect
- (UIImage*) createGrayCopy:(UIImage*) source {
int width = source.size.width;
int height = source.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGContextRef context = CGBitmapContextCreate (nil, width,
height,
8, // bits per component
0,
colorSpace,
kCGImageAlphaNone);
CGColorSpaceRelease(colorSpace);
if (context == NULL) {
return nil;
}
CGContextDrawImage(context,
CGRectMake(0, 0, width, height), source.CGImage);
UIImage *grayImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];
CGContextRelease(context);
return grayImage;
}
Search for OpenCV

How can i choose UIImage for glReadPixels?

I have a view with 50 images. Images may overlap. I want (for example) select image number 33 and find pixel color. How can i do this ?
PS i use glReadPixels.
Unless you want to kill time applying the image as a texture first, you wouldn't use glReadPixels. You can do this directly from the UIImage instead:
void pixelExamine( UIImage *image )
{
CGImageRef colorImage = image.CGImage;
int width = CGImageGetWidth(colorImage);
int height = CGImageGetHeight(colorImage);
uint32_t *pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t));
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), colorImage);
int x;
int y;
uint8_t *rgbaPixel;
for( y = 0; y < height; y++)
{
rgbaPixel = (uint8_t *) &pixels[y * width];
for( x = 0; x < width; x++, rgbaPixel+=4)
{
// rgbaPixel[0] = ALPHA 0..255
// rgbaPixel[3] = RED 0..255
// rgbaPixel[2] = GREEN 0..255
// rgbaPixel[1] = BLUE 0..255
}
}
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
free(pixels);
}

iPhone Image Processing--matrix convolution

I am implementing a matrix convolution blur on the iPhone. The following code converts the UIImage supplied as an argument of the blur function into a CGImageRef, and then stores the RGBA values in a standard C char array.
CGImageRef imageRef = imgRef.CGImage;
int width = imgRef.size.width;
int height = imgRef.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *pixels = malloc((height) * (width) * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * (width);
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(pixels, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
Then the pixels values stored in the pixels array are convolved, and stored in another array.
unsigned char *results = malloc((height) * (width) * 4);
Finally, these augmented pixel values are changed back into a CGImageRef, converted to a UIImage, and the returned at the end of the function with the following code.
context = CGBitmapContextCreate(results, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGImageRef finalImage = CGBitmapContextCreateImage(context);
UIImage *newImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];
CGImageRelease(finalImage);
NSLog(#"edges found");
free(results);
free(pixels);
CGColorSpaceRelease(colorSpace);
return newImage;
This works perfectly, once. Then, once the image is put through the filter again, very odd, unprecedented pixel values representing input pixel values that don't exist, are returned. Is there any reason why this should work the first time, but then not afterward? Beneath is the entirety of the function.
-(UIImage*) blur:(UIImage*)imgRef {
CGImageRef imageRef = imgRef.CGImage;
int width = imgRef.size.width;
int height = imgRef.size.height;
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
unsigned char *pixels = malloc((height) * (width) * 4);
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * (width);
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(pixels, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
height = imgRef.size.height;
width = imgRef.size.width;
float matrix[] = {1,1,1,1,1,1,1,1,1};
float divisor = 9;
float shift = 0;
unsigned char *results = malloc((height) * (width) * 4);
for(int y = 1; y < height; y++){
for(int x = 1; x < width; x++){
float red = 0;
float green = 0;
float blue = 0;
int multiplier=1;
if(y>0 && x>0){
int index = (y-1)*width + x;
red = matrix[0]*multiplier*(float)pixels[4*(index-1)] +
matrix[1]*multiplier*(float)pixels[4*(index)] +
matrix[2]*multiplier*(float)pixels[4*(index+1)];
green = matrix[0]*multiplier*(float)pixels[4*(index-1)+1] +
matrix[1]*multiplier*(float)pixels[4*(index)+1] +
matrix[2]*multiplier*(float)pixels[4*(index+1)+1];
blue = matrix[0]*multiplier*(float)pixels[4*(index-1)+2] +
matrix[1]*multiplier*(float)pixels[4*(index)+2] +
matrix[2]*multiplier*(float)pixels[4*(index+1)+2];
index = (y)*width + x;
red = red+ matrix[3]*multiplier*(float)pixels[4*(index-1)] +
matrix[4]*multiplier*(float)pixels[4*(index)] +
matrix[5]*multiplier*(float)pixels[4*(index+1)];
green = green + matrix[3]*multiplier*(float)pixels[4*(index-1)+1] +
matrix[4]*multiplier*(float)pixels[4*(index)+1] +
matrix[5]*multiplier*(float)pixels[4*(index+1)+1];
blue = blue + matrix[3]*multiplier*(float)pixels[4*(index-1)+2] +
matrix[4]*multiplier*(float)pixels[4*(index)+2] +
matrix[5]*multiplier*(float)pixels[4*(index+1)+2];
index = (y+1)*width + x;
red = red+ matrix[6]*multiplier*(float)pixels[4*(index-1)] +
matrix[7]*multiplier*(float)pixels[4*(index)] +
matrix[8]*multiplier*(float)pixels[4*(index+1)];
green = green + matrix[6]*multiplier*(float)pixels[4*(index-1)+1] +
matrix[7]*multiplier*(float)pixels[4*(index)+1] +
matrix[8]*multiplier*(float)pixels[4*(index+1)+1];
blue = blue + matrix[6]*multiplier*(float)pixels[4*(index-1)+2] +
matrix[7]*multiplier*(float)pixels[4*(index)+2] +
matrix[8]*multiplier*(float)pixels[4*(index+1)+2];
red = red/divisor+shift;
green = green/divisor+shift;
blue = blue/divisor+shift;
if(red<0){
red=0;
}
if(green<0){
green=0;
}
if(blue<0){
blue=0;
}
if(red>255){
red=255;
}
if(green>255){
green=255;
}
if(blue>255){
blue=255;
}
int realPos = 4*(y*imgRef.size.width + x);
results[realPos] = red;
results[realPos + 1] = green;
results[realPos + 2] = blue;
results[realPos + 3] = 1;
}else {
int realPos = 4*((y)*(imgRef.size.width) + (x));
results[realPos] = 0;
results[realPos + 1] = 0;
results[realPos + 2] = 0;
results[realPos + 3] = 1;
}
}
}
context = CGBitmapContextCreate(results, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGImageRef finalImage = CGBitmapContextCreateImage(context);
UIImage *newImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];
CGImageRelease(finalImage);
free(results);
free(pixels);
CGColorSpaceRelease(colorSpace);
return newImage;}
THANKS!!!
The problem was that I was assuming the alpha value, needed to calculate it like the RGB values.