stktrc
stktrc

Reputation: 1639

Access iPhone Absolute Pixel Position

In the screenspace of an iPhone/iPad, Apple uses points, which are typically half the actual resolution of the screen. My question is, is it possible to access the actual pixels themselves? For example, if i take a UIView, and make it have a size/location of 0,0,0.5,0.5 with a background color of red, i can't see it on the screen.

Just wondering if this is possible.

Thanks!

Upvotes: 0

Views: 227

Answers (2)

Hamish
Hamish

Reputation: 80911

Sure it's possible.

The code you already have should be working (a UIView with a size of (0.5, 0.5)). I just ran it and captured this result from the simulator:

enter image description here

Yea. That's difficult to see. Let's zoom that in.

enter image description here

So yes, you can draw on-screen in smaller values than a single point.

However, to draw a single pixel, you'll want to be using a point value that is 1/scaleOfScreen (as not all devices have 2x displays). So, for example, you'll want your code to look something like this:

CGFloat scale = [UIScreen mainScreen].scale;
CGFloat pixelPointWidth = 1/scale;    

UIView* v = [[UIView alloc] initWithFrame:CGRectMake(20, 20, pixelPointWidth, pixelPointWidth)];
v.backgroundColor = [UIColor redColor];
[self.view addSubview:v];

This will now create a UIView that occupies a single pixel on-screen.

Although, if you want to be doing a lot of pixel-perfect drawing, you should probably be using something lower level than a single UIView (have a look at Core Graphics).


However.

You may encounter some issues with this method when drawing on an iPhone 6 Plus. Because it's screen's scale differs from its nativeScale, it will first render your content in the logical coordinate space of 3x and then downsample to the actual screen resolution (around 2.6x).

This will most probably result in some pixel bleeding, where your 'pixel' view can be rendered in neighboring pixels (although usually at a reduced brightness).

Unfortunately, there is no easy way around this problem without using an even lower level API such as OpenGL or Metal, where you can circumvent this automatic scaling and then downsampling, and draw directly into the screen's actual coordinate space.


  • Have a look here for a nice little overview on how different devices render content onto their screens.

  • Have a look here for more info on how pixel bleeding can occur on the iPhone 6 Plus.

Upvotes: 1

H4Hugo
H4Hugo

Reputation: 2650

You can guess the pixels based on the point depending on the device resolution (in ppi) by multiplying a coefficient but you don't want to do this.

Also, in your exemple you did not state that you normalized the coordinates so basically you are trying to display a red box at the first pixel (top left) with a size of half a point, which is why you can't see it.

EDIT

To draw a red box you can use this sample code :

//  Draw a red box
[[UIColor redColor] set];
UIRectFill(CGRectMake(20, 20, 100, 100)); // position (x : 20, y: 20) (still top left) and size (100*100 points)

Upvotes: 0

Related Questions