UIImageView content pixels (ingore image padding) - iphone

The short version: How do I know what region of a UIImageView contains the image, and not aspect ratio padding?
The longer version:
I have a UIImageView of fixed size as pictured:
I am loading photos into this UIViewController, and I want to retain the original photo's aspect ratio so I set the contentMode to Aspect Fit. This ends up ensuring that the entire photo is displayed within the UIImageView, but with the side effect of adding some padding (configured in red):
No problem so far.... But now I am doing face detection on the original image. The face detection code returns a list of CGRects which I then render on top of the UIImageView (I have a subclassed UIView and then laid out an instance in IB which is the same size and offset as the UIImageView).
This approach works great when then photo is not padded out to fit into UIImageView. However if there is padding, it introduces some skew as seen here in green:
I need to take the image padding into account when rendering the boxes, but I do not see a way to retrieve it.
Since I know the original image size and the UIImageView size, I can do some algebra to calculate where the padding should be. However it seems like there is probably a way to retrieve this information, and I am overlooking it.

I do not use image views often so this may not be the best solution. But since no one else has answered the question I figured I'd through out a simple mathematical solution that should solve your problem:
UIImage *selectedImage; // the image you want to display
UIImageView *imageView; // the imageview to hold the selectedImage
NSInteger heightOfView = imageView.frame.size.height;
NSInteger heightOfPicture = selectedImage.size.height;
NSInteger yStartingLocationForGreenSquare; // set it to whatever the current location is
// take whatever you had it set to and add the value of the top padding
yStartingLocationForGreenSquare += (heightOfView - heightOfPicture) / 2;
So although there may be other solutions this is a pretty simple math formula to accomplish what you need. Hope it helps.

Related

How to capture screen after applying mask to the layer in iOS?

I added two UIView to ViewController.view, and applied 2 squares image into each view.layer.mask to make it like a square is sliced into 2 pieces, and addSubview the imageview over it.

I am having a problem rendering the masked layers and save it to photo album.
I want the saved photo to be look like picture no. 1, but it always looks like picture no. 2 after I save it to photo album.

Is there any solution to capture like picture No. 1 after applying mask?
the below is the reference from apple regarind renderIngContext.
Important The OS X v10.5 implementation of this method does not support the entire Core Animation composition model. QCCompositionLayer, CAOpenGLLayer, and QTMovieLayer layers are not rendered. Additionally, layers that use 3D transforms are not rendered, nor are layers that specify backgroundFilters, filters, compositingFilter, or a mask values. Future versions of OS X may add support for rendering these layers and properties.
I've created an image capture function before, which literally does a printscreen of a UIView. I don't use it, because it does not work well for my needs but maybe you can use it:
UIImage *img;
UIGraphicsBeginImageContextWithOptions(UIViewYouWantToCapture.bounds.size, self.opaque, 0.0);
[[UIViewYouWantToCapture layer] renderInContext:UIGraphicsGetCurrentContext()];
img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
When we apply masking to any image then the we get the resultant image with alpha property of masked image to 1 and remaining image to 0,
and when we are capturing image of view then there is still complete image(we are able to seen half image due due to alpa = 0 of half image, but there is still a complete image) , so we getting the screenshot of complete view.

CGRectIntegral what is the usage of it?

How does one use the CGRectIntegral function? I understand it's purpose.
The documentation isn't clear on it's exact use.
CGRectIntegral to convert any decimal values to their integer equivalents
see image may be you can understand
How do I fix it?
frame = CGRectIntegral(frame);
-OR-
myTextView.frame = CGRectIntegral(myTextView.frame);
 
see this for more information of CGRectIntegral
CGRectIntegral Method is used to create integer rect . I mean to say suppose if you calculate frame in app you may get frames value in float.
Setting float value as frame to some UIElement like UILabel would make the text looks blur. To avoid that, we use CGRectIntegral.Please look at the example below,
NSLog(#"%#",NSStringFromCGRect( CGRectIntegral(CGRectMake(0, 15.6, 16.1, 20.2))));
This will print, {0,15},{17,21}.
This explanation is found in the header file.
/* Expand `rect' to the smallest rect containing it with integral origin and
size. */
One particular usage is to fix frames that do not align perfectly with on-screen pixels.
See this question: UITextField blurred text
If a label or textfield has a frame that isn't pixel-aligned when rendered to the screen, the text will appear blurred. This can happen if you calculate the frame using division (for example to center it in a parent view).
CGRectIntegral will remove the fractional part of the frame, fixing this problem. Note however that with retina displays a .5 frame value is pixel aligned, but CGRectIntgral will still remove the fractional part.

UISlider minimumValueImageRectForBounds: and super maximumValueImageRectForBounds returns empty rectangle

I subclass UISlider in order to make the thumb smaller, and I want to override minimumValueImageRectForBounds and maximumValueImageRectForBounds to make their width 2px less. So my code is
- (CGRect)minimumValueImageRectForBounds:(CGRect)bounds
{
CGRect stdRect = [super minimumValueImageRectForBounds:bounds];
return CGRectMake(stdRect.origin.x + 2, stdRect.origin.y, stdRect.size.width - 2, stdRect.size.height);
}
The point is that stdRect is empty rectangle (0, 0, 0, 0).
Morover, if I explicitly set some rectangle like that
- (CGRect)minimumValueImageRectForBounds:(CGRect)bounds
{
return CGRectMake(2, 0, 40, 8);
}
It doesn't affect minimum value image position at all.
Any ideas?
Haha, I just figured it out. I wasn't reading closely enough.
Setting the minimumValueImage is not the same as calling setMinimumTrackImage:forState:. The minimumValueImage is an image that gets displayed to the left of the slider and is independent what's going on in the slider. Overriding minimumValueImageRectForBounds changes the dimensions of this image (the default size being 0pt wide) and the sliders frame is made less wide and shifted to the right as a result. As I understand it, there isn't a way to modify the rectangle of the minimumTrackImage (such as to make it extend to the right of the thumb image); it is only possible to change the image.
I haven't really figured out the point of allowing you to set the minimumValueImage. It seems like you could accomplish the same thing by changing the size of the slider and adding separate UIImageViews to the side of the slider. Who knows.
Note that everything I've said here applies in the same way for the maximumValueImage and setMaximumTrackImage:forState methods.
DO NOT DO THIS. This is an old, incorrect answer, by past me. I hate that guy.
--
As a general rule, you probably don't want to subclass the Apple standard UI controls. You might want to build it up and set those properties yourself instead (not sure if they are settable, but seems like they should be).

Custom UITextField

How would I go about creating a UITextField like the one in this image?
It appears to be slightly larger, specifically in height.
This can be done much better and simpler with a stretchable image:
UIImage *fieldBGImage = [[UIImage imageNamed:#"input.png"] stretchableImageWithLeftCapWidth:20 topCapHeight:20];
[myUITextField setBackground:fieldBGImage];
Think of the background of the text field as split into three sections. A middle section which can be stretched and caps on the ends. Create an image which only needs to be long enough to contain one pixel of this repeating section (a very short text field), and then create a stretchable image from it using stretchableImageWithLeftCapWidth: topCapHeight. Pass the width of the left end cap into 'leftCapWidth.' You can make it stretch vertically as well, but if your background image is the same height as your text box it wont have an effect.
If you're familiar with 9-slice scaling in Flash or Illustrator it's exactly the same concept, except the middle sections are only one pixel wide/tall.
The advantage of this is you don't have to worry about multiple layered objects scaling together and you can resize your text fields any time and the background will stay in tact. It works on other elements too!
You probably want to use the background and borderStyle properties of UITextField. Setting borderStyle as UITextBorderStyleNone and create a custom background image to be stretched and used as the background property would be one approach.
I suggest taking a look at those properties in the UITextField class reference.
You can do this by:
yourTextField.borderStyle = UITextBorderStyleNone;
yourTextField.background = [UIImage imageNamed:#"email-input.png"];
And if you want to give margin to your text inside the textfield, you can do this by:
// Setting Text Field Margins to display the user entered text Properly
UIView *paddingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 5, 20)];
yourTextField.leftView = paddingView;
yourTextField.leftViewMode = UITextFieldViewModeAlways;
You can also do this through Interface Builder.
just use the following line and it should work
textfield_name.background = [UIImage imageNamed : #"yourImage.png"];
here, "yourImage" is the background image you wanna set...
however, this will work only if your button isnt a roundrect button.So, you can change the type of the button in the Interface Builder or you can use
textfield_name.borderstyle = UITextBorderStyleNone or UITextBorderStyleBezel
and you r gud2go....!
Take an uiimageview set its image property to the image you want as uitextfield background. And on top of this uiimageview place an uitextfield with borderstyle none. This you can do directly in interface builder.

drawAtPoint: and drawInRect: blurry text

When drawing strings using drawAtPoint:, drawInRect: and even setting the text property of UILabels - the text can sometimes appear slightly blurry.
I tend to use Helvetica in most places, and I notice that specific font sizes cause some level of blurriness to occur, both in the simulator and on the device.
For example:
UIFont *labelFont = [UIFont fontWithName:#"Helvetica-Bold" size:12];
Will cause the resulting label to have slightly blurry text.
UIFont *labelFont = [UIFont fontWithName:#"Helvetica-Bold" size:13];
Results in crisp text.
My question is why does this occur? And is it just a matter of selecting an optimal font size for a typeface? If so, what are the optimal font sizes?
UPDATE: It seems that perhaps it is not the font size that is causing the blurriness. It may be that the center of the rect is a fractional point. Here is a comment I found on the Apple dev forums:
Check the position. It's likely on a
fractional pixel. Change center to be
integer value.
I rounded off the values of all my points, but there are still places where text remains blurry. Has anyone come across this issue before?
I have resolved this.
Just make sure that the point or rect in which you are drawing does not occur on a fractional pixel.
I.e. NSLog(#"%#", NSStringFromCGRect(theRect)) to determine which point is being drawn on a fractional pixel. Then call round() on that point.
You might want to look at NSIntegralRect(), it does what you want.
Pardon my ignorance if this is incorrect, I know nothing about iPhone or Cocoa.
If you're asking for the text to be centered in the rect, you might also need to make sure the width and/or height of the rect is an even number.
I have had this problem too, but my solution is different and may help someone.
My problem was text blur after changing the size of a UIView object thru TouchesBegan
and CGAffineTransformMakeScale, then back to CGAffineTransformIdentity in TouchesEnded.
I tried both the varying text size and rounding of x and y center points but neither worked.
The solution for my problem was to use even sizes for the width and height of my UIView !!
Hope this helps ....
From my experiments, some fonts don't render clearly at certain sizes. e.g. Helvetica-Bold doesn't render "." well at 16.0f, but they're clear at 18.0f. (If you look closely, the top pixel of the "." is blurry.)
After I noticed that, I've been irked every time I see that UIView, since it's rendered dynamically.
In my case, I drew text on a custom CALayer and turned out to be pretty blurry. I solved it by setting contentScale with appropriate value:
Objective-C:
layer.contentsScale = [UIScreen mainScreen].scale;
Swift:
layer.contentsScale = UIScreen.main.scale