iphone taking grayscale screenshot? - iphone

I'm wondering if there is a SIMPLE way to take a Grayscale screenshot, i know i can take color screenshot like this:
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSData *data = UIImagePNGRepresentation(image);
now what i need to add in these lines of code to make the UIImage Grayscaled? thank you for reading.

Just convert your image to gray scale.
Read this post. Good luck.
Here is the method:d
#pragma mark -
#pragma mark Grayscale
- (UIImage *)convertImageToGrayScale:(UIImage *)image
{
// Create image rectangle with current image width/height
CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);
// Grayscale color space
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
// Create bitmap content with current image size and grayscale colorspace
CGContextRef context = CGBitmapContextCreate(nil, image.size.width, image.size.height, 8, 0, colorSpace, kCGImageAlphaNone);
// Draw image into current context, with specified rectangle
// using previously defined context (with grayscale colorspace)
CGContextDrawImage(context, imageRect, [image CGImage]);
// Create bitmap image info from pixel data in current context
CGImageRef imageRef = CGBitmapContextCreateImage(context);
// Create a new UIImage object
UIImage *newImage = [UIImage imageWithCGImage:imageRef];
// Release colorspace, context and bitmap information
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
CFRelease(imageRef);
// Return the new grayscale image
return newImage;
}

Based on Cam's code with the ability to deal with the scale for Retina displays.
- (UIImage *) toGrayscale
{
// Create image rectangle with current image width/height
CGRect imageRect = CGRectMake(0, 0, self.size.width * self.scale, self.size.height * self.scale);
int width = imageRect.size.width;
int height = imageRect.size.height;
// the pixels will be painted to this array
uint32_t *pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t));
// clear the pixels so any transparency is preserved
memset(pixels, 0, width * height * sizeof(uint32_t));
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// create a context with RGBA pixels
CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace,
kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
// paint the bitmap to our context which will fill in the pixels array
CGContextDrawImage(context, CGRectMake(0, 0, width, height), [self CGImage]);
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
uint8_t *rgbaPixel = (uint8_t *) &pixels[y * width + x];
// convert to grayscale using recommended method: http://en.wikipedia.org/wiki/Grayscale#Converting_color_to_grayscale
uint32_t gray = 0.3 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.11 * rgbaPixel[BLUE];
// set the pixels to gray
rgbaPixel[RED] = gray;
rgbaPixel[GREEN] = gray;
rgbaPixel[BLUE] = gray;
}
}
// create a new CGImageRef from our context with the modified pixels
CGImageRef image = CGBitmapContextCreateImage(context);
// we're done with the context, color space, and pixels
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
free(pixels);
// make a new UIImage to return
UIImage *resultUIImage = [UIImage imageWithCGImage:image
scale:self.scale
orientation:UIImageOrientationUp];
// we're done with image now too
CGImageRelease(image);
return resultUIImage;
}

Related

How t draw outline/stroke around UIImage (*.png) - Example inside

I tried many many ways to draw a black outline around image.
This is an example of the result I want:
Can someone please let me know how should I do it? or give me an example ?
Edit: i stuck in here: can someone please help me finish it ?
What i did was to make another shape in black color under the the white with shadow and then fill it all in black so it will be like an outline - but i cant figure out how to make the last and important part of making the shadow and fill it to be all in black.
- (IBAction)addStroke:(id)sender{
[iconStrokeTest setImage:[self makeIconStroke:icon.imageView.image]];
}
- (UIImage *)makeIconStroke:(UIImage *)image{
CGImageRef originalImage = [image CGImage];
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapContext = CGBitmapContextCreate(NULL,
CGImageGetWidth(originalImage),
CGImageGetHeight(originalImage),
8,
CGImageGetWidth(originalImage)*4,
colorSpace,
kCGImageAlphaPremultipliedLast);
CGContextDrawImage(bitmapContext, CGRectMake(0, 0, CGBitmapContextGetWidth(bitmapContext), CGBitmapContextGetHeight(bitmapContext)), originalImage);
CGImageRef finalMaskImage = [self createMaskWithImageAlpha:bitmapContext];
UIImage *result = [UIImage imageWithCGImage:finalMaskImage];
CGContextRelease(bitmapContext);
CGImageRelease(finalMaskImage);
// begin a new image context, to draw our colored image onto
UIGraphicsBeginImageContext(result.size);
// get a reference to that context we created
CGContextRef context = UIGraphicsGetCurrentContext();
// set the fill color
[[UIColor blackColor] setFill];
// translate/flip the graphics context (for transforming from CG* coords to UI* coords
CGContextTranslateCTM(context, 0, result.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
// set the blend mode to color burn, and the original image
CGContextSetBlendMode(context, kCGBlendModeColorBurn);
CGRect rect = CGRectMake(0, 0, result.size.width, result.size.height);
CGContextDrawImage(context, rect, result.CGImage);
// set a mask that matches the shape of the image, then draw (color burn) a colored rectangle
CGContextClipToMask(context, rect, result.CGImage);
CGContextAddRect(context, rect);
CGContextDrawPath(context,kCGPathFill);
// generate a new UIImage from the graphics context we drew onto
UIImage *coloredImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//return the color-burned image
return coloredImg;
}
- (CGImageRef)createMaskWithImageAlpha:(CGContextRef)originalImageContext {
UInt8 *data = (UInt8 *)CGBitmapContextGetData(originalImageContext);
float width = CGBitmapContextGetBytesPerRow(originalImageContext) / 4;
float height = CGBitmapContextGetHeight(originalImageContext);
int strideLength = ROUND_UP(width * 1, 4);
unsigned char * alphaData = (unsigned char * )calloc(strideLength * height, 1);
CGContextRef alphaOnlyContext = CGBitmapContextCreate(alphaData,
width,
height,
8,
strideLength,
NULL,
kCGImageAlphaOnly);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
unsigned char val = data[y*(int)width*4 + x*4 + 3];
val = 255 - val;
alphaData[y*strideLength + x] = val;
}
}
CGImageRef alphaMaskImage = CGBitmapContextCreateImage(alphaOnlyContext);
CGContextRelease(alphaOnlyContext);
free(alphaData);
// Make a mask
CGImageRef finalMaskImage = CGImageMaskCreate(CGImageGetWidth(alphaMaskImage),
CGImageGetHeight(alphaMaskImage),
CGImageGetBitsPerComponent(alphaMaskImage),
CGImageGetBitsPerPixel(alphaMaskImage),
CGImageGetBytesPerRow(alphaMaskImage),
CGImageGetDataProvider(alphaMaskImage), NULL, false);
CGImageRelease(alphaMaskImage);
return finalMaskImage;
}
Well, theres no build-in API for that. You'll have to do it yourself or find a libary for this. But you could "fake" the effect by drawing the image with a shadow. Note that shadows can be any color, it doesn't have to look like a shadow. This would be the easiest way.
Other than that you could vectorize the raster image and stroke that path. Core image's edge detection filter will help for that but it could turn out to be hard to acomplish.

Change brightness on a greyscale image with transparent background

I use a function to change brightness of a picture (without use openGL), which works well.
I use another function to convert my image in grayscale, which works well too.
But when i combine them, when i apply my brightness function on the grayscale image, i got some stripes on the image, and when the background is transparent (alpha 0) it is replaced by a black background. Do you any have any idea?
Please find below my grayscale function and the brightness function as well :
// ## Brightness without OpenGL call
+(UIImage *) changeImageBrightness:(UIImage *)aInputImage withFactor:(float)aFactor
{
CGImageRef img=aInputImage.CGImage;
CFDataRef dataref = CGDataProviderCopyData(
CGImageGetDataProvider(aInputImage.CGImage));
int length=CFDataGetLength(dataref);
UInt8 *data=(UInt8 *)CFDataGetBytePtr(dataref);
// Perform operation on pixels
for(int index=0;index<length;index+=4) {
// Go For BRIGHTNESS
for(int i=0;i<3;i++) {
if(data[index+i]+aFactor<0) {
data[index+i]=0;
} else {
if(data[index+i]+aFactor>255) {
data[index+i]=255;
} else {
data[index+i]+=aFactor;
}
}
}
}
// .. Take image attributes
size_t width=CGImageGetWidth(img);
size_t height=CGImageGetHeight(img);
size_t bitsPerComponent=CGImageGetBitsPerComponent(img);
size_t bitsPerPixel=CGImageGetBitsPerPixel(img);
size_t bytesPerRow=CGImageGetBytesPerRow(img);
// .. Do the pixel manupulation
CGColorSpaceRef colorspace=CGImageGetColorSpace(img);
CGBitmapInfo bitmapInfo=CGImageGetBitmapInfo(img);
CFDataRef newData=CFDataCreate(NULL,data,length);
CGDataProviderRef provider=CGDataProviderCreateWithCFData(newData);
// .. Get the Image out of this raw data
CGImageRef newImg = CGImageCreate(width, height, bitsPerComponent,
bitsPerPixel, bytesPerRow, colorspace, bitmapInfo, provider,
NULL, true, kCGRenderingIntentDefault);
// .. Prepare the image from raw data
UIImage* rawImage = [[UIImage alloc] initWithCGImage:newImg];
// .. done with all,so release the references
CFRelease(newData);
CGImageRelease(newImg);
CGDataProviderRelease(provider);
CFRelease(dataref);
// return rawImage.CGImage;
UIImage *imageApresFiltreEtRotationCGI = [UIImage
imageWithCGImage:rawImage.CGImage];
return imageApresFiltreEtRotationCGI;
}
+ (UIImage *)convertImageToGrayScale:(UIImage *)image
{
// Create image rectangle with current image width/height
CGRect imageRect = CGRectMake(0, 0, image.size.width, image.size.height);
// Grayscale color space
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
// Create bitmap content with current image size and grayscale colorspace
CGContextRef context = CGBitmapContextCreate(nil, image.size.width,
image.size.height, 8, 0, colorSpace, kCGImageAlphaNone);
// Draw image into current context, with specified rectangle
// using previously defined context (with grayscale colorspace)
CGContextDrawImage(context, imageRect, [image CGImage]);
/* changes start here */
// Create bitmap image info from pixel data in current context
CGImageRef grayImage = CGBitmapContextCreateImage(context);
// release the colorspace and graphics context
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
// make a new alpha-only graphics context
context = CGBitmapContextCreate(nil, image.size.width,
image.size.height, 8, 0, nil, kCGImageAlphaOnly);
// draw image into context with no colorspace
CGContextDrawImage(context, imageRect, [image CGImage]);
// create alpha bitmap mask from current context
CGImageRef mask = CGBitmapContextCreateImage(context);
// release graphics context
CGContextRelease(context);
// make UIImage from grayscale image with alpha mask
UIImage *grayScaleImage = [UIImage imageWithCGImage:
CGImageCreateWithMask(grayImage, mask) scale:image.scale
orientation:image.imageOrientation];
// release the CG images
CGImageRelease(grayImage);
CGImageRelease(mask);
// return the new grayscale image
return grayScaleImage;
/* changes end here */
}
Here is the picture i got.
The background behind the baby was transparent before i made the grey/scale and light transformation.

iOS Capture screen, then crop and mask the result image

In my application, I want to do the following steps:
1 - Capture the screen, this part is no problem for me, I'm using the following code:
- (UIImage *)captureScreen {
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, YES, 0.0f);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
2 - I cropped the image with this function
- (UIImage *)cropImage(UIImage *)image inRect:(CGRect)rect {
CGImageRef imageRef = CGImageCreateWithImageInRect(image.CGImage, rect);
UIImage *resultImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
return resultImage;
}
3 - Then I mask the cropped image with a pure black and white mask
- (UIImage *)maskImage:(UIImage *)image withMask:(UIImage *)maskImage {
CGImageRef maskRef = maskImage.CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
CGImageGetHeight(maskRef),
CGImageGetBitsPerComponent(maskRef),
CGImageGetBitsPerPixel(maskRef),
CGImageGetBytesPerRow(maskRef),
CGImageGetDataProvider(maskRef), NULL, false);
CGImageRef maskedRef = CGImageCreateWithMask([image CGImage], mask);
UIImage *resultImage = [UIImage imageWithCGImage:maskedRef];
CGImageRelease(mask);
CGImageRelease(maskedRef);
return resultImage;
}
However, the result image I got is that outside the shape of the mask, the image is in black color instead of transparent. Can anybody help me?
This Works for me. Hope it will work for you too.
- (UIImage*) doImageMask:(UIImage *)mainImage:(UIImage*)maskImage{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGImageRef maskImageRef = [maskImage CGImage];
// create a bitmap graphics context the size of the image
CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
if (mainViewContentContext == NULL){
return NULL;
}
CGFloat ratio = 0;
ratio = maskImage.size.width/ mainImage.size.width;
if(ratio * mainImage.size.height < maskImage.size.height) {
ratio = maskImage.size.height/ mainImage.size.height;
}
CGRect rect1 = {{0, 0}, {maskImage.size.width, maskImage.size.height}};
CGRect rect2 = {{-((mainImage.size.width*ratio)-maskImage.size.width)/2 , -((mainImage.size.height*ratio)-maskImage.size.height)/2}, {mainImage.size.width*ratio, mainImage.size.height*ratio}};
CGContextClipToMask(mainViewContentContext, rect1, maskImageRef);
CGContextDrawImage(mainViewContentContext, rect2, mainImage.CGImage);
// Create CGImageRef of the main view bitmap content, and then
// release that bitmap context
CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext);
CGContextRelease(mainViewContentContext);
UIImage *theImage = [UIImage imageWithCGImage:newImage];
CGImageRelease(newImage);
// return the image
return theImage;
}
I solve my problem, it is due to the alpha channel of the image to be masked. So before masking, I create another UIImage with alpha channel and continue my steps.
This is the code for creating a UIImage with alpha
- (UIImage *)imageWithAlpha {
CGImageRef imageRef = self.CGImage;
CGFloat width = CGImageGetWidth(imageRef);
CGFloat height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(nil, width, height, 8, 4 * width, colorSpace, kCGImageAlphaPremultipliedFirst);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGImageRef resultImageRef = CGBitmapContextCreateImage(context);
UIImage *resultImage = [UIImage imageWithCGImage:resultImageRef scale:self.scale orientation:self.imageOrientation];
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
CGImageRelease(resultImageRef);
return resultImage;
}

How can i change uiimage color in iphone sdk xcode

I am using different images and i want to include change color option. But i cant. Any body help me?
If you want to do image tinting, see UIImage+Tint.m in kballard/MGImageUtilities. If you want wholesale color replacement (e.g. treat an image as a silhouette and change the entire color to one flat color), see UIImage+Tint.m in mattgemmell/MGImageUtilities.
Its latest and most simple way to do it.
theImageView.image = [theImageView.image imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[theImageView setTintColor:[UIColor redColor]];
One way to accomplish this is to desaturate your image, and add a tint on top of that image with the color you desire.
Desaturate
-(UIImage *) getImageWithUnsaturatedPixelsOfImage:(UIImage *)image {
const int RED = 1, GREEN = 2, BLUE = 3;
CGRect imageRect = CGRectMake(0, 0, image.size.width*2, image.size.height*2);
int width = imageRect.size.width, height = imageRect.size.height;
uint32_t * pixels = (uint32_t *) malloc(width*height*sizeof(uint32_t));
memset(pixels, 0, 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), [image CGImage]);
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
uint8_t * rgbaPixel = (uint8_t *) &pixels[y*width+x];
uint32_t gray = (0.3*rgbaPixel[RED]+0.59*rgbaPixel[GREEN]+0.11*rgbaPixel[BLUE]);
rgbaPixel[RED] = gray;
rgbaPixel[GREEN] = gray;
rgbaPixel[BLUE] = gray;
}
}
CGImageRef newImage = CGBitmapContextCreateImage(context);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);
free(pixels);
UIImage * resultUIImage = [UIImage imageWithCGImage:newImage scale:2 orientation:0];
CGImageRelease(newImage);
return resultUIImage;
}
Overlay With Color
-(UIImage *) getImageWithTintedColor:(UIImage *)image withTint:(UIColor *)color withIntensity:(float)alpha {
CGSize size = image.size;
UIGraphicsBeginImageContextWithOptions(size, FALSE, 2);
CGContextRef context = UIGraphicsGetCurrentContext();
[image drawAtPoint:CGPointZero blendMode:kCGBlendModeNormal alpha:1.0];
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextSetBlendMode(context, kCGBlendModeOverlay);
CGContextSetAlpha(context, alpha);
CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(CGPointZero.x, CGPointZero.y, image.size.width, image.size.height));
UIImage * tintedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return tintedImage;
}
How-To
//For a UIImageView
yourImageView.image = [self getImageWithUnsaturatedPixelsOfImage:yourImageView.image];
yourImageView.image = [atom getImageWithTintedColor:yourImageView.image withTint:[UIColor redColor] withIntensity:0.7];
//For a UIImage
yourImage = [self getImageWithUnsaturatedPixelsOfImage:yourImage];
yourImage = [atom getImageWithTintedColor:yourImageView.image withTint:[UIColor redColor] withIntensity:0.7];
You can change the color of the tint to whatever you desire.

Drawing into CGImageRef

I want to create a CGImageRef and draw points to it.
What context to use to create an empty CGImageRef and be able to draw onto it.
CGContextRef or CGBitmapContextRef?
If you can provide code to create an empty CGImageRef image and draw to it I would appreciate.
#define HIRESDEVICE (((int)rintf([[[UIScreen mainScreen] currentMode] size].width/[[UIScreen mainScreen] bounds].size.width )>1))
- (CGImageRef) blerg
{
CGFloat imageScale = (CGFloat)1.0;
CGFloat width = (CGFloat)180.0;
CGFloat height = (CGFloat)180.0;
if ( HIRESDEVICE )
{
imageScale = (CGFloat)2.0;
}
// Create a bitmap graphics context of the given size
//
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, width * imageScale, height * imageScale, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast);
// Draw ...
//
CGContextSetRGBFillColor(context, (CGFloat)0.0, (CGFloat)0.0, (CGFloat)0.0, (CGFloat)1.0 );
// …
// Get your image
//
CGImageRef cgImage = CGBitmapContextCreateImage(context);
CGColorSpaceRelease(colorSpace);
CGContextRelease(context);
return cgImage;
}