Image drawing problem when using CGContext. Image is mirrored horizontally - iphone

When I am drawing UIImage* image on UIView using the below code, the image is mirrored horizontally. It is like that if I draw 4, it is drawing like this ..
CGRect rect = CGRectMake(x, y, imageWidth, imageHeight);
CGContextDrawImage((CGContextRef) g, rect, ((UIImage*)image).CGImage);
That is the problem??? I am doing wrong??? or if somebody know how to fix it, please let me also know. I very appreciate that in advance.
Thanks a loooooooooot.

See: CGContextDrawImage draws image upside down when passed UIImage.CGImage
Use [image drawInRect:rect] instead of CGContextDrawImage.

you can turn the picture the right way around using
CGAffineTransform transform =CGAffineTransformMakeTranslation(0.0, height);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
CGContextConcatCTM(context, transform);
//draw image in the context
CGContextDrawImage(context, rect, ((UIImage*)image).CGImage);
Using [image drawInRect:rect] uses the default context i.e. the screen, you can not give it your current context, e.g. if you want to put it as part of a button's ima

Related

gradient cut from top to bottom

This is a follow up question to - gradient direction from left to right
In this apple refection sample code,
Apple Reflection Example
when the size slider is moved, the image is cut from bottom to top. How can I cut it from top to bottom when the slider is moved? I am trying to understand this tutorial better
//I know the code is in this section here but I can't figure out what to change
- (UIImage *)reflectedImage:(UIImageView *)fromImage withHeight:(NSUInteger)height
{
...
}
//it probably has something to do with this code.
//I think this tells it how much to cut.
//Though I can't figure out how does it know where the 0,0 of the image is and why
// keep 0,0 of the image on the top? I am assuming this is where it hinges its
//point and cuts the image from bottom to top
CGContextRef MyCreateBitmapContext(int pixelsWide, int pixelsHigh)
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
// create the bitmap context
CGContextRef bitmapContext = CGBitmapContextCreate (NULL, pixelsWide, pixelsHigh, 8, 0, colorSpace,(kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));
CGColorSpaceRelease(colorSpace);
return bitmapContext;
}
What if the image to reflect was on the top. So in order to show it properly, I need to reveal it from top down, not bottom up. That;s the effect I am trying to achieve. In this case I just moved the UIImageViews around in their storyboard example. You now see my dilemma
it's very similar to #Putz1103 answer. You should create a new method starting from the previous - (UIImage *)reflectedImage:(UIImageView *)fromImage withWidth:(NSUInteger)width.
- (UIImage *)reflectedImage:(UIImageView *)fromImage withWidth:(NSUInteger)width andHeight:(NSUInteger)height
{
....
CGContextClipToMask(mainViewContentContext, CGRectMake(0.0, 0.0, width, height), gradientMaskImage);
....
}
Then in slideAction method, use something like:
self.reflectionView.image = [self reflectedImage:self.imageView withWidth:self.imageView.bounds.size.width andHeight:reflectionHeight];
Good luck!
My guess would be this line:
CGContextClipToMask(mainViewContentContext, CGRectMake(0.0, 0.0, fromImage.bounds.size.width, height), gradientMaskImage);
If you change it to this it should do the opposite:
CGContextClipToMask(mainViewContentContext, CGRectMake(0.0, fromImage.bounds.size.height - height, fromImage.bounds.size.width, height), gradientMaskImage);
Basically you need to set the clipping rectangle to the bottom of the image instead of the top of the image. This will invert what your slider does, but that is easy to resolve and I'll leave that for your exercise.

What's wrong with the way I have tried to flip (mirror) a UIImage?

I have been attempting this for a few days now. I'm creating a sprite sheet loader, however I must also be able to load the sprites facing the opposite direction. This involves flipping the images that I already have loaded.
I have already attempted to do this using the UIImageOrientation / UIImageOrientationUpMirrored method however this has absolutely no effect and simply draws the frame with the exact same orientation as before.
I have since attempted a slightly more complicated way which I will include below. But still, simply draws the image in exactly the same way as it is loaded into the application. (Not mirrored).
I've included the method below (along with my comments so that you can maybe follow my thought pattern), can you see what I am doing wrong?
- (UIImage*) getFlippedFrame:(UIImage*) imageToFlip
{
//create a context to draw that shizz into
UIGraphicsBeginImageContext(imageToFlip.size);
CGContextRef currentContext = UIGraphicsGetCurrentContext();
//WHERE YOU LEFT OFF. you're attempting to find a way to flip the image in imagetoflip. and return it as a new UIimage. But no luck so far.
[imageToFlip drawInRect:CGRectMake(0, 0, imageToFlip.size.width, imageToFlip.size.height)];
//take the current context with the old frame drawn in and flip it.
CGContextScaleCTM(currentContext, -1.0, 1.0);
//create a UIImage made from the flipped context. However will the transformation survive the transition to UIImage? UPDATE: Apparently not.
UIImage* flippedFrame = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return flippedFrame;
}
Thank you,
Guy.
I would have expected that you have to change the transform of the context and then draw. Also, you would need to translate because you are flipping to negative coordinates, so, replace
[imageToFlip drawInRect:CGRectMake(0, 0, imageToFlip.size.width, imageToFlip.size.height)];
CGContextScaleCTM(currentContext, -1.0, 1.0);
with (edited based on comments)
CGContextTranslateCTM(currentContext, imageToFlip.size.width, 0);
CGContextScaleCTM(currentContext, -1.0, 1.0);
[imageToFlip drawInRect:CGRectMake(0, 0, imageToFlip.size.width, imageToFlip.size.height)];
NOTE: From comments, a category to use
#implementation UIImage (Flip)
- (UIImage*)horizontalFlip {
UIGraphicsBeginImageContext(self.size);
CGContextRef current_context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(current_context, self.size.width, 0);
CGContextScaleCTM(current_context, -1.0, 1.0);
[self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)];
UIImage *flipped_img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return flipped_img;
}
#end

MKOverlay View is blurred

I'm trying to add a png image as a custom map using MKOverlayView. I'm almost there - I am able to get the image lined up in the right place, and I know that the -drawMapRect: method in the subclass of MKOverlayView is being called periodically; I just can't seem to get the image to render properly. It's totally blurry, almost beyond recognition. I also know the image is large enough (it is 1936 × 2967). Here is my code for -drawMapRect:
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context{
// Load image from applicaiton bundle
NSString* imageFileName = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"map.jpg"];
CGDataProviderRef provider = CGDataProviderCreateWithFilename([imageFileName UTF8String]);
CGImageRef image = CGImageCreateWithJPEGDataProvider(provider, NULL, true, kCGRenderingIntentDefault);
CGDataProviderRelease(provider);
// save context before screwing with it
CGContextSaveGState(context);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetAlpha(context, 1.0);
// get the overlay bounds
MKMapRect theMapRect = [self.overlay boundingMapRect];
CGRect theRect = [self rectForMapRect:theMapRect];
// Draw image
CGContextDrawImage(context, theRect, image);
CGImageRelease(image);
CGContextRestoreGState(context);
Does anyone have a clue what's going on?
Thanks!
-Matt
I've had a similar problem. The problem was that my boundingMapRect was defined incorrectly. The full image is rendered scaled down when the scale is small on a tile. Then the map is zoomed and not all the image tiles are in the boundingMapRect tiles so they are not redrawn in the correct scale and the scaled down version is zoomed. At least that's what I think happens.
Hope this helps.
Get rid of CGContextScaleCTM(context, 1.0, -1.0); and do a vertical flip on your image in preview instead. the mapkit seems to use the context information to determine which part of the image to render more clearly. Know it's been a while, but hope it helps!
Thanks Rob, you made my day. My blur overlay image got sharpen when I replaced
CGContextScaleCTM(context, 1.0, -1.0);
with
CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, theRect.size.height);
CGContextConcatCTM(context, flipVertical);

Save a UIImage from a UIImageView with CGAffineTransform

I have a UIImageView within a UIScrollView which I have enabled the user to perform any number of flip and rotation operations on. I have this all working which allows the user to zoom, pan, flip and rotate. Now I want to be able to save the final image out to a png.
however it is doing my head in trying to work this out...
I have seen quite a few other posts similar to this but most only require applying a single transform such as a rotation eg Creating a UIImage from a rotated UIImageView
I would like to apply any transform that the user has "created" which will be a series of flip and rotations concatenated togethers
As the user is applying various rotations, flips etc, I store the concatenated transform using CGAffineTransformConcat. For example when they rotate I do:
CGAffineTransform newTransform = CGAffineTransformMakeRotation(angle);
self.theFullTransform = CGAffineTransformConcat(self.theFullTransform, newTransform);
self.fullPhotoImageView.transform = self.theFullTransform;
The following method is the best I have gotten so far for creating a UIImage with the full transform however the image is always translated in the wrong place. Eg the image is "offset". Which my guess is either related to using the wrong bounds being set in in CGAffineTransformTranslate or CGContextDrawImage.
Does anyone have any ideas? This seems a lot harder that I thought it should be...
- (UIImage *) translateImageFromImageView: (UIImageView *) imageView withTransform:(CGAffineTransform) aTransform
{
UIImage *rotatedImage;
// Get image width, height of the bounding rectangle
CGRect boundingRect = CGRectApplyAffineTransform(imageView.bounds, aTransform);
// Create a graphics context the size of the bounding rectangle
UIGraphicsBeginImageContext(boundingRect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGAffineTransform transform = CGAffineTransformIdentity;
//I think this translaton is the problem?
transform = CGAffineTransformTranslate(transform, boundingRect.size.width/2, boundingRect.size.height/2);
transform = CGAffineTransformScale(transform, 1.0, -1.0);
transform = CGAffineTransformConcat(transform, aTransform);
CGContextConcatCTM(context, transform);
// Draw the image into the context
// or the boundingRect is incorrect here?
CGContextDrawImage(context, boundingRect, imageView.image.CGImage);
// Get an image from the context
rotatedImage = [UIImage imageWithCGImage: CGBitmapContextCreateImage(context)];
// Clean up
UIGraphicsEndImageContext();
return rotatedImage;
}
Is the offset predictable, like always half the image, or does it depend on aTransform?
struct CGAffineTransform {
CGFloat a, b, c, d;
CGFloat tx, ty;
};
If the latter, set tx and ty to zero in aTransform before using it.

Image drawing on PDF fails to draw image with transformation and outputs wrong

I've a problem with drawing images on PDF. I do apply scaling, rotation, move, etc. to an image and draws that image on the PDF. But drawing is not outputting correctly. When I do rotate image, it just scales and doesn't rotate.
Here, I explain in more detail:
I place an image on UIWebView to make fake effect of image exactly on PDF. Then, I do draw image on PDF which is on the UIWebView while making PDF.
But when I go and prepare PDF with modified image, which has been applied lots of transformations, image scales not rotates.
Here, img_copyright is a Custom class inheriting UIImageView.
CGFloat orgY = (newY-whiteSpace)+img_copyright.frame.size.height;
CGFloat modY = pageRect.size.height-orgY;
CGFloat orgX = img_copyright.frame.origin.x-PDF_PAGE_PADDING_WIDTH;
CGFloat modX = orgX;
//We're getting X,Y of the image here to decide where to put the image on PDF.
CGRect drawRect = CGRectMake (modX, modY, img_copyright.frame.size.width, img_copyright.frame.size.height);
//Preparing the rectangle in which image is to be drawn.
CGContextDrawImage(pdfContext, drawRect, [img_copyright.image CGImage]);
[img_copyright release];
// Actually drawing the image.
But when i see the PDF image is not properly drawn into it.
What would you suggest, is it the problem due to image drawing based on its X,Y?
How could we decide where to put the image on PDF if we don't depend on X, Y?
What is the exact method of drawing image on PDF with rotation, scale?
The Image when I do insert the image onto UIWebView's scrollbar.
http://www.freeimagehosting.net/">
The Image when I do draw the image onto PDF.
http://www.freeimagehosting.net/">
CGFloat angleInRadians =-1*Angle* (M_PI / 180.0);
CGAffineTransform transform=CGAffineTransformIdentity;
transform = CGAffineTransformMakeRotation(angleInRadians);
//transform = CGAffineTransformMakeScale(1, -1);
//transform =CGAffineTransformMakeTranslation(0,80);
CGRect rotatedRect = CGRectApplyAffineTransform(CGRectMake(0,0,Image.size.width,Image.size.height), transform);
UIGraphicsBeginImageContext(rotatedRect.size);
//[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), 0,rotatedRect.size.height);
CGContextScaleCTM(UIGraphicsGetCurrentContext(),1, -1);
//CGContextTranslateCTM(UIGraphicsGetCurrentContext(), +(rotatedRect.size.width/2),+(rotatedRect.size.height/2));
CGContextTranslateCTM(UIGraphicsGetCurrentContext(), (rotatedRect.origin.x)*-1,(rotatedRect.origin.y)*-1);
CGContextRotateCTM(UIGraphicsGetCurrentContext(), angleInRadians);
//CGContextTranslateCTM(UIGraphicsGetCurrentContext(), -(rotatedRect.size.width/2),-(rotatedRect.size.height/2));
CGImageRef temp = [Image CGImage];
CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, Image.size.width,Image.size.height), temp);
//CGContextRotateCTM(UIGraphicsGetCurrentContext(), -angleInRadians);
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;