I am Rotating the image by using this code
- (CGImageRef)CGImageRotatedByAngle:(CGImageRef)imgRef angle:(CGFloat)angle
{
CGFloat angleInRadians = angle * (M_PI / 360);
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGRect imgRect = CGRectMake(0, 0, width, height);
CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians);
CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bmContext = CGBitmapContextCreate(NULL,
rotatedRect.size.width,
rotatedRect.size.height,
8,
0,
colorSpace,
kCGImageAlphaPremultipliedFirst);
CGContextSetAllowsAntialiasing(bmContext, YES);
CGContextSetShouldAntialias(bmContext, YES);
CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh);
CGColorSpaceRelease(colorSpace);
CGContextTranslateCTM(bmContext,
+(rotatedRect.size.width/2),
+(rotatedRect.size.height/2));
CGContextRotateCTM(bmContext, angleInRadians);
CGContextTranslateCTM(bmContext,
-(rotatedRect.size.width/2),
-(rotatedRect.size.height/2));
CGContextDrawImage(bmContext, CGRectMake(0, 0,
rotatedRect.size.width,
rotatedRect.size.height),
imgRef);
CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext);
CFRelease(bmContext);
// [(id)rotatedImage autorelease];
return rotatedImage;
}
By this i am having the resultant image like this..
those white spaces should not be there and it should follow the same pattern of that size with out that white spaces around..the rotated image....
Please help..Thanks in advance
Related
I have been trying to measure glyph bounds precisely but this code prints out 916!!! The real width of this is 69.
- (void)drawRect:(NSRect)dirtyRect {
CGContextRef main = [[NSGraphicsContext currentContext] graphicsPort];
CGContextSetTextMatrix(main, CGAffineTransformIdentity);
CGGlyph g;
CGPoint p = CGPointMake(100, 100);
CGRect rect = CGRectMake(0, 0, 0, 0);
CGFontRef font = CGFontCreateWithFontName((CFStringRef)#"Arial");
g = CGFontGetGlyphWithGlyphName(font, CFSTR("L"));
CGContextSetFont(main, font);
CGContextSetTextPosition(main, 0, 0);
CGContextSetFontSize(main, 200);
CGContextSetRGBFillColor(main, 0, 0, 1, 1);
CGContextShowGlyphsAtPositions(main, &g, &p, 1);
CGFontGetGlyphBBoxes(font, &g, 1, &rect);
printf("%f", rect.size.width);
}
You are using CGFontGetGlyphBBoxes, which returns the size in glyph space units. To use this, you need to scale it with the units per em and the font size.
CGRect rect;
CGFontRef font = CGFontCreateWithFontName((CFStringRef)#"Arial");
CGFloat fontSize = 200.0;
CGGlyph g = CGFontGetGlyphWithGlyphName(font, CFSTR("L"));
CGFontGetGlyphBBoxes(font, &g, 1, &rect);
CGFloat width = rect.size.Width / CGFontGetUnitsPerEm(font) * fontSize;
An alternate way to do it to use [NSFont boundingRectForCGGlyph:].
NSFont *font = [NSFont fontWithName:#"Arial" size:200];
NSRect rect = [font boundingRectForCGGlyph:g];
boundingRectForCGGlyph
Returns the bounding rectangle for the specified glyph, scaled to the receiver’s size.
Have following code for rotation:
CGFloat angleInRadians = angle * M_PI/180.0;
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGRect imgRect = CGRectMake(width, height, width, height);
CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians);
CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bmContext = CGBitmapContextCreate(NULL,
rotatedRect.size.width,
rotatedRect.size.height,
8,
0,
colorSpace,
(CGBitmapInfo)kCGImageAlphaPremultipliedFirst);
CGContextSetAllowsAntialiasing(bmContext, true);
CGContextSetShouldAntialias(bmContext, true);
CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh);
CGColorSpaceRelease(colorSpace);
CGContextTranslateCTM(
bmContext,
+(rotatedRect.size.width/2),
+(rotatedRect.size.height/2));
CGContextRotateCTM(bmContext, angleInRadians);
CGContextTranslateCTM(
bmContext,
-(rotatedRect.size.width/2),
-(rotatedRect.size.height/2));
CGContextDrawImage(bmContext, CGRectMake(0, 0, rotatedRect.size.width, rotatedRect.size.height), imgRef);
CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext);
return rotatedImage;
As a result I getting distorted image. What I'm doing wrong here?
.
.
.
CGRect imgRect = CGRectMake(0., 0., width, height); // origin at {0, 0}; not {width, height}
.
.
.
CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext);
CGImageRelease(bmContext); // don't need this anymore
.
.
.
As commented, the origin is at 0.0, 0.0 not at width or height.
I can't solve this problem. Load image, convert to CGImageRef. Try to get bitmap context and render on the screen.
NSURL *imageFileURL = [NSURL fileURLWithPath:stringIMG];
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)imageFileURL, NULL);
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
NSInteger bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
NSInteger bitsPerPixel = CGImageGetBitsPerPixel(imageRef);
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
NSInteger bytesPerRow = CGImageGetBytesPerRow(imageRef);
NSInteger width = CGImageGetWidth(imageRef);
NSInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorspace = CGImageGetColorSpace(imageRef);
size_t rawData = bytesPerRow*height;
unsigned char *data = malloc(rawData);
memset(data2, 0, rawData);
CGContextRef context = CGBitmapContextCreate(data, width, height, bitsPerComponent, bytesPerRow, colorspace, bitmapInfo);
CGImageRef imageRef2 = CGBitmapContextCreateImage(context);
// CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef2);
UIImage *result = [UIImage imageWithCGImage:imageRef2];//if i do like this i got white empty screen
UIImageView *image = [[UIImageView alloc] initWithImage:result];
[self.view addSubview:image];// if i do like this i got black rectangle on the white screen
I have no idea. I check by breakpoint that context is not null. I don't know what should i do. Please maybe anyone can help me?
Category added it to UIImage for resizing using CoreGraphics
UIImage+Resize.h
#import <UIKit/UIKit.h>
#interface UIImage (Resizing)
-(UIImage*)resizedImageWithSize:(CGSize)size;
#end
UIImage+Resizing.m
#import "UIImage+Resizing.h"
#implementation UIImage (Resizing)
-(UIImage*)resizedImageWithSize:(CGSize)size {
CGImageRef cgImage = [self CGImage];
size_t bitsPerComponent = CGImageGetBitsPerComponent(cgImage);
size_t bytesPerRow = CGImageGetBytesPerRow(cgImage);
CGColorSpaceRef colorSpace = CGImageGetColorSpace(cgImage);
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(cgImage);
CGContextRef context = CGBitmapContextCreate(nil, size.width, size.height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGContextDrawImage(context, CGRectMake(0, 0, size.width, size.height), cgImage);
CGImageRef resizedImageRef = CGBitmapContextCreateImage(context);
UIImage *resizedImage = [UIImage imageWithCGImage:resizedImageRef];
CFRelease(resizedImageRef);
CFRelease(context);
return resizedImage;
}
#end
This function return a black image. I use the Sparrow Library.
This is my code :
-(UIImage *) saveRectangle:(SPRectangle*)rectangle
{
int numberOfComponents = 8;
int width = rectangle.width;
int height = rectangle.height;
NSInteger bufferLenght = width * height * numberOfComponents;
NSMutableData * buffer= [NSMutableData dataWithLength:bufferLenght];
glPixelStorei(GL_PACK_ALIGNMENT, 4); // force 4 byte alignment
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, [buffer mutableBytes]);
CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, [buffer mutableBytes], bufferLenght, NULL);
CGImageRef iref = CGImageCreate(width, height, 8, 32, width * 4, CGColorSpaceCreateDeviceRGB(), kCGBitmapByteOrderDefault, ref, NULL, true, kCGRenderingIntentDefault);
uint32_t* pixels = (uint32_t *)malloc(bufferLenght);
CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width*4, CGImageGetColorSpace(iref), kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big);
CGContextTranslateCTM(context, 0.0, height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(context, CGRectMake(0.0, 0.0, width, height), iref);
CGImageRef outputRef = CGBitmapContextCreateImage(context);
free(pixels);
return [UIImage imageWithCGImage:outputRef];
}
The code you show has very little Sparrow code to it (other than the SPRectangle which is very akin to a CGRect). Sounds like you're trying to save a capture of a rectangular area of a Sparrow scene. Sparrow intends to abstract you from the OpenGL implementation details. Are you sure it wouldn't be easier to just use an SPRenderTexture? http://doc.sparrow-framework.org/core/Classes/SPRenderTexture.html
Also be sure you want to return an UIImage and not a SPImage. Hope it helps.
I'm writing code to use UIImagePickerController. Corey previously posted some nice sample code on SO related to cropping and scaling. However, it doesn't have implementations of cropImage:to:andScaleTo: nor straightenAndScaleImage().
Here's how they're used:
newImage = [self cropImage:originalImage to:croppingRect andScaleTo:scaledImageSize];
...
UIImage *rotatedImage = straightenAndScaleImage([editInfo objectForKey:UIImagePickerControllerOriginalImage], scaleSize);
Since I'm sure someone must be using something very similar to Corey's sample code, there's probably an existing implementation of these two functions. Would someone like to share?
If you check the post you linked to, you'll see a link to the apple dev forums where I got some of this code, here are the methods you are asking about. Note: I may have made some changes relating to data types, but I can't quite remember. It should be trivial for you to adjust if needed.
- (UIImage *)cropImage:(UIImage *)image to:(CGRect)cropRect andScaleTo:(CGSize)size {
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGImageRef subImage = CGImageCreateWithImageInRect([image CGImage], cropRect);
CGRect myRect = CGRectMake(0.0f, 0.0f, size.width, size.height);
CGContextScaleCTM(context, 1.0f, -1.0f);
CGContextTranslateCTM(context, 0.0f, -size.height);
CGContextDrawImage(context, myRect, subImage);
UIImage* croppedImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGImageRelease(subImage);
return croppedImage;
}
UIImage *straightenAndScaleImage(UIImage *image, int maxDimension) {
CGImageRef img = [image CGImage];
CGFloat width = CGImageGetWidth(img);
CGFloat height = CGImageGetHeight(img);
CGRect bounds = CGRectMake(0, 0, width, height);
CGSize size = bounds.size;
if (width > maxDimension || height > maxDimension) {
CGFloat ratio = width/height;
if (ratio > 1.0f) {
size.width = maxDimension;
size.height = size.width / ratio;
}
else {
size.height = maxDimension;
size.width = size.height * ratio;
}
}
CGFloat scale = size.width/width;
CGAffineTransform transform = orientationTransformForImage(image, &size);
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
// Flip
UIImageOrientation orientation = [image imageOrientation];
if (orientation == UIImageOrientationRight || orientation == UIImageOrientationLeft) {
CGContextScaleCTM(context, -scale, scale);
CGContextTranslateCTM(context, -height, 0);
}else {
CGContextScaleCTM(context, scale, -scale);
CGContextTranslateCTM(context, 0, -height);
}
CGContextConcatCTM(context, transform);
CGContextDrawImage(context, bounds, img);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}