How to blur UIImage excluding specific point. - objective-c

In GPUImageGaussianSelectiveBlurFilter how to set the point of non image blur ? i tried setting the point excludeCirclePoint but everything gets blur. I want to implement touches gesture and the touched point remains good while the other image gets blur.

You have to assign CGPoint to filter's excludeCirclePoint property where CGPointMake(0, 0) is the top-left corner of the image and CGPointMake(1, 1) is the bottom-right corner.
Something like:
GPUImageGaussianSelectiveBlurFilter *filter = [[GPUImageGaussianSelectiveBlurFilter alloc] init];
filter.excludeCirclePoint = CGPointMake(0.5, 0.5); // center

Related

Pinch Gesture Zoom only Zooms UIImage from Upper Left Corner

I am fairly new to this and I'm trying to use pinch gestures to zoom in on a UIImage and be able to zoom into any specific part of the image. However, when I zoom it only zooms from the upper left corner of the UIView. So I only get to see the upper left corner of the image zoomed in. I'd like to be able to zoom/pan the image similar to how the Photos app works. Here is my code so far:
In ViewDidLoad:
...
// Load the image to be viewed into the UIImage
self.theImage.image = self.theNewImage;
UIPinchGestureRecognizer *pinchGestRecog = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:#selector(twoFingerPinch:)];
// ADD GESTURE RECOGNIZER TO THE VIEW
[theImage addGestureRecognizer:pinchGestRecog];
// ALLOW USER INTERACTION ON THE VIEW
[theImage setUserInteractionEnabled:YES];
// SET IMAGE ZOOM SCALE LIMITS
imageCurrentScale = 1.0;
imageMaxScale = 2.0;
imageMinScale = 0.5;
And then in my twoFingerPinch method:
- (void)twoFingerPinch:(UIPinchGestureRecognizer *)aPinchGesture
{
if (imageCurrentScale * [aPinchGesture scale] > imageMinScale && imageCurrentScale * [aPinchGesture scale] < imageMaxScale) {
imageCurrentScale = imageCurrentScale * [aPinchGesture scale];
CGAffineTransform zoomTransform = CGAffineTransformMakeScale(imageCurrentScale, imageCurrentScale);
[[aPinchGesture view] setTransform:zoomTransform];
}
[aPinchGesture setScale:1.0];
}
Is panning somehow the answer? I'm not really sure how panning works.
Any suggestions? Thanks.
The reason why you zoom to your upper left corner is because the center of your scale transformation is the UIView.layer.anchorPoint which is default the upper left corner (0,0).
If you want to zoom correctly you somehow have to figure out the center of your pinch gesture and then set your anchorPoint to that position.
But you shouldn't do that anyway. The recommended way to zoom into a UIImageView is to place the the image view into a UIScrollView and set the contentSize and maximumZoomScale and minimumZoomScale values accordingly.
Set yourself as the delegate of your UIScrollView and return the UIImageView in the viewForZooming delegate method.
The scrollview will handle the pinching and zooming for you.

When I set the anchor point, my image is not loading

I have a UIView on which i am loading my image view as a sub view. The image is showing when i doesn't set the anchor point but whenever i set anchor point the image is not showing .I have added the QUARTZCore frame work also.
I am adding my code below
CGRect apprect=CGRectMake(0, 0, 1024, 768);
UIView *containerView = [[UIView alloc] initWithFrame:apprect1];
containerView.backgroundColor = [UIColor whiteColor];
[self.view addSubview:containerView];
handleView1= [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"large.gif"]];
[handleView1 setAlpha:1];
//[handleView1 setFrame:CGRectMake(390, 172.00, 56.00, 316.00)];
handleView1.userInteractionEnabled = YES;
handleView1.layer.anchorPoint=CGPointMake(490.0, 172.0);
[containerView addSubview:handleView1];
The problem are the values you use for the anchorPoint. You don't set points like for the position of a frame as values. Let me quote Apple:
The anchorPoint property is a CGPoint
that specifies a location within the
bounds of a layer that corresponds
with the position coordinate. The
anchor point specifies how the bounds
are positioned relative to the
position property, as well as serving
as the point that transforms are
applied around. It is expressed in
the unit coordinate system-the
(0.0,0.0) value is located closest to
the layer’s origin and (1.0,1.0) is
located in the opposite corner.
Have a look at Layer Geometry and Transforms in the Core Animation Programming Guide for more details.
First set the Frame of your ImageView and then set the ancherpoint like this
[ handleView1.layer setAnchorPoint:CGPointMake(1, 1)];

Subclassing NSScroller, how to get rid of the white square in the lower right corner?

I've created an iTunes like subclass of NSScroller, however if both the horizontal and vertical scrollers are visible in an NSScrollView or NSTableView I'm left with an ugly white square in the lower right corner. Anyone has a clue on where to add my custom drawing to fill that in with something prettier?
Ok, I think I have the solution(s).
Either you tell the scrollview not to draw its background, in that case anything below it will fill the corner.
Or, which is what I did, you override the scrollview's drawRect method with the following:
- (void)drawRect:(NSRect)rect{
[super drawRect: rect];
if([self hasVerticalScroller] && [self hasHorizontalScroller]){
NSRect vframe = [[self verticalScroller]frame];
NSRect hframe = [[self horizontalScroller]frame];
NSRect corner;
corner.origin.x = NSMaxX(hframe);
corner.origin.y = NSMinY(hframe);
corner.size.width = NSWidth(vframe);
corner.size.height = NSHeight(hframe);
// your custom drawing in the corner rect here
}
}

NSImage rotation

I have a window with an subclass of NSView in it. Inside the view, I put an NSImage.
I want to be able to rotate the image by 90 degrees, keeping the (new) upper left corner of the image in the upper left corner of the view. Of course, I will have to rotate the image, and then translate it to put the origin back into place.
In Carbon, I found CGContextRotateCTM which does what I want . However, I can't find the right call in ObjC. setFrameCenterRotation doesn't seem to do anything, and in setFrameRotation, I can't seem to figure out where the origin is, so I can approprately translate.
It seems to move. When I resize the window it puts the image (or part of it, I seem to have a strange clipping issue as wel) and when I scroll, it jumps to a different (and not always the saem) location.
Does this make sense to anyone?
thanks
I rotate text on the screen for an app I work on and the Cocoa (I assume you mean Cocoa and not ObjC in your question) way of doing this is to use NSAffineTransform.
Here's a snippet that should get you started
double rotateDeg = 90;
NSAffineTransform *rotate = [[NSAffineTransform alloc] init];
NSGraphicsContext *context = [NSGraphicsContext currentContext];
[context saveGraphicsState];
[rotate rotateByDegrees:rotateDeg];
[rotate concat];
/* Your drawing code [NSImage drawAtPoint....]for the image goes here
Also, if you need to lock focus when drawing, do it here. */
[rotate release];
[context restoreGraphicsState];
The mathematics on the rotation can get a little tricky here because what the above does is to rotate the coordinate system that you are drawing into. My rotation of 90 degrees is a counter-clockwise rotation.

How do I pan the image inside a UIImageView?

I have a UIImageView that is displaying an image that is wider and taller than the UIImageView is. I would like to pan the image within the view using an animation (so that the pan is nice and smooth).
It seems to me that I should be able to just adjust the bounds.origin of the UIImageView, and the image should move (because the image should paint inside the view with that as its origin, right?) but that doesn't seem to work. The bounds.origin changes, but the image draws in the same location.
What almost works is to change the contentsRect of the view's layer. But this begins as a unit square, even though the viewable area of the image is not the whole image. So I'm not sure how I would detect that the far edge of the image is being pulled into the viewable area (which I need to avoid, since it displays by stretching the edge out to infinity, which looks, well, sub-par).
My view currently has its contentsGravity set to kCAGravityTopLeft via Interface Builder, if that makes a difference (Is it causing the image to move?). No other options seemed to be any better, though.
UPDATE: to be clear, I want to move the image inside the view, while keeping the view in the same spot.
I'd highly recommend enclosing your UIImageView in a UIScrollView. Have the UIImageView display the full image, and set the contentSize on the UIScrollView to be the same as your UIImageView's size. Your window into the image will be the size of the UIScrollView, and by using scrollRectToVisible:animated: you can pan to particular areas on the image in an animated fashion.
If you don't want scroll bars to appear, you can set the showsHorizontalScrollIndicator and showsVerticalScrollIndicatorproperties to NO.
UIScrollView also provides pinch-zooming functionality, which may or may not be useful to you.
Brad Larson pointed me down the right road with his suggestion to put the UIImageView inside a UIScrollView.
In the end I put the UIImageView inside of a UIScrollView, and set the scrollView's contentSize and the imageView's bounds to be the same size as the image in the UIImage:
UIImage* image = imageView.image;
imageView.bounds = CGRectMake(0, 0, image.size.width, image.size.height);
scrollView.contentSize = image.size;
Then, I can animate the scrollView's contentOffset to achieve a nice panning effect:
[UIView beginAnimations:#"pan" context:nil];
[UIView setAnimationDuration:animationDuration];
scrollView.contentOffset = newRect.origin;
[UIView commitAnimations];
In my particular case, I'm panning to a random space in the image. In order to find a proper rect to pan to and a proper duration to get a nice constant speed, I use the following:
UIImage* image = imageView.image;
float xNewOrigin = [TCBRandom randomIntLessThan:image.size.width - scrollView.bounds.size.width];
float yNewOrigin = [TCBRandom randomIntLessThan:image.size.height - scrollView.bounds.size.height];
CGRect oldRect = scrollView.bounds;
CGRect newRect = CGRectMake(
xNewOrigin,
yNewOrigin,
scrollView.bounds.size.width,
scrollView.bounds.size.height);
float xDistance = fabs(xNewOrigin - oldRect.origin.x);
float yDistance = fabs(yNewOrigin - oldRect.origin.y);
float hDistance = sqrtf(powf(xDistance, 2) + powf(yDistance, 2));
float hDistanceInPixels = hDistance;
float animationDuration = hDistanceInPixels / speedInPixelsPerSecond;
I'm using a speedInPixelsPerSecond of 10.0f, but other applications might want to use a different value.