How can I avoid using CATiledLayer when rendering a PDF? - iphone

I have been trying to render PDF documents into a CATiledLayer, but this appears to be slowing down the rendering process on the iPad.
I've also tried using a normal layer, but I've not seen an improvement.
Is there any alternative to using a CATiledLayer for rendering a PDF?

CATiledLayer is necessary either by itself or as a backing layer for a UIView when you are attempting to display a view or layer that exceeds the maximum texture size supported by the GPU. Apple lists this as 1024x1024 for the iPhone, but in my experience I've been able to go up to 2048x2048 on even the first-generation iPhone.
If you are able to render to a view or layer that is smaller in both width and height than those dimensions, you don't need to use a CATiledLayer and can get away with a standard layer. The tiling process does slow rendering a bit as it brings in the appropriate tiles, so you could gain some performance that way.
For a discussion on general PDF rendering performance, I direct you to this question:
Fast and Lean PDF Viewer for iPhone / iPad / iOs - tips and hints?

Related

How to maintain text clarity of image while zooming?

I am developing an app for a magazine and simultaneously I am creating images for those magazines using photo shop.
But, when I zoom these images, the text quality is getting loosed.
I have referred to other iPad magazines like India Today. In that, even though I zoom to maximum extent, text quality is too good.
how is that possible? My each image size is almost 800 KB. Even then, when I zoom, I loose the clarity of image. How to maintain the quality of text even when I zoom?
Is that something to do with photoshop editing or coding?
We use the following table for our iPhone/iPad projects when the OS target is 3.2 or above.
Because you are using raster graphics you are in a losing battle of file size vs. zoom quality. Text is natively vector and scales beautifully as you zoom, so you are much better off rendering text as text rather than generating text as an image in Photoshop. There are many ways to accomplish this, one being to have the image be a background layer and the text be a UILabel above the image.

Preloading a large image

I have an image with the dimensions of 5534 × 3803, and size of 2.4mb. The UIView references notes that:
"In iOS 3.0 and later, views are no longer restricted to this maximum
size but are still limited by the amount of memory they consume."
When the image loads, it lags for half a second, then slides in. The image sits in the UIImageView at 1024x704, but can be scaled up to 4x that size for the purpose of my app.
Are you able to preload the image in the AppDelegate? Or is there another way of working around having such a large image?
Thanks
EDIT: The scaling is done via UIPinchGestureRecognizer, and scales up and done (scale x4 - x1) based on the image's center point. There is no panning of the image when zoomed in.
Personally, I would try to write a tile-based system (think Google Maps) that slices your big image into a grid of small images to avoid loading in that gigantic image all at once into RAM. I don't really know what your user interactions are for this image, or whether the images are changing or baked into your project, but I'd assume you can let users scroll around since that image is bigger than any iOS screen. With a tile-based system, you only load the images that are on-screen. CATiledLayer is an Apple class for doing just such a thing. That's probably what you want to look into.
See this StackOverflow question for some different approaches. The accepted answer uses code from Apple's sample PhotoScroller project, which may work for your needs and uses CATiledLayer.
This ScrollViewSuite Apple code might also get on your way (check out the Tiling code).

iPhone image resource - 1024 maximum, 2048 pixels #2x?

The restriction of 1024x1024 as the largest image for an iPhone is a problem with iPhone 4. However if an #2x image is used with maximum dimensions of 2048x2048 everything looks equally good on the 4 as it does on a 3 - tried and tested in simulator and device. Question is, does the image dimension restriction relate to the UIImage or the resource that it contains? I can't imagine resources of more than 1024 pixels are discouraged with the 960 pixel height of the screen.
The right answer is really to use tiles so that things look even better, but the deadline for for this deliverable is too close - it's a future thing.
From UIImage class reference:
You should avoid creating UIImage
objects that are greater than 1024 x
1024 in size. Besides the large amount
of memory such an image would consume,
you may run into problems when using
the image as a texture in OpenGL ES or
when drawing the image to a view or
layer. This size restriction does not
apply if you are performing code-based
manipulations, such as resizing an
image larger than 1024 x 1024 pixels
by drawing it to a bitmap-backed
graphics context. In fact, you may
need to resize an image in this manner
(or break it into several smaller
images) in order to draw it to one of
your views.
That is, views are rendered and composited with the iPhone's GPU. If your view, for example, overrides drawRect and tries to render a very big UIImage you might run into problems. Newer generation iDevices, such as iPad and iPhone 4 support bigger textures than 1024x1024 (2048x2048 I think).
I didn't realise there was a restriction, I'm using an image 15198 × 252 as the scrolling landscape in Scramble... works really well, though I must say I did have reservations before I tried it out!

Will OpenGL give me any FPS improvement over CoreAnimation for scrolling a large image?

I'm considering re-writing the menu system of my iPhone app to use Open GL just to improve the smoothness of scrolling a big image (480x1900px) across the screen.
I'm looking at doing this as a way to improve on using the method/solution as described here (Smoother UIView). This solution was a big improvement over the previous implementation but it's still not perfect and as this is the first thing the user will see I'd like it to be as flawless as possible.
Will switching to OpenGL give me the sort of smooth scrolling I'm looking for? I've stayed clear of OpenGL until now as this is my first app and core animation has handled everything else I've thrown at it well enough, would be good to know if this alternative implementation is likely to work! thanks
You should be using CATiledLayer for images that big. From the UIView docs:
Regardless of which version of iPhone
OS is running, you should consider
using a CATiledLayer object if you
need to create views larger than 1024
x 1024 in size.
Bill Dudney posted the CATiledLayer example from his Core Animation book on his blog. Unless you're building a graphics intensive game, you shouldn't need to drop down into OpenGL. Core Animation should give you all of the performance you need.

Image strategy in iPhone app

I'm writing a card game for the iPhone, and I'm not sure about the best strategy for displaying the cards. I have a basic prototype that creates a UIImageView that can be dragged for each card with a dummy image. I wanted to use one large UIImage that contains the faces of all of the cards, and then have each draggable UIImageView display a part of that image. I must be misunderstanding what setBounds is for - I thought that controlled which part of the underlying image is displayed. So, two questions:
Is this the right approach?
How do I display just a part of the image?
Depending on your resolution, this might not be the best approach.
From Apple:
You should avoid creating UIImage
objects that are greater than 1024 x
1024 in size. Besides the large amount
of memory such an image would consume,
you may run into problems when using
the image as a texture in OpenGL ES or
when drawing the image to a view or
layer. This size restriction does not
apply if you are performing code-based
manipulations, such as resizing an
image larger than 1024 x 1024 pixels
by drawing it to a bitmap-backed
graphics context. In fact, you may
need to resize an image in this manner
(or break it into several smaller
images) in order to draw it to one of
your views.
Now, you are talking about breaking it up into several smaller pieces, but given UIIMage's caching, I am not sure what happens to memory every time you access the image and copy a sub-rect out of it. I think the approach I would take is to have an array of images, instead of one big one.