Getting a tiled image collection on the iPad (Deep Zoom) - iphone

I have a set of tiled image collections created via Microsoft's Deep Zoom composer, and a Silverlight application that currently consumes them for display via MultiScaleImage - it's all working pretty well - I'd just like to get some experience with iPad programming and
have a couple of ideas for some iPad applications. All my ideas rely on me being able to display/manipulate these tiled image sets (on the iPad).
I just picked up a iMac to facilitate this. I'm not seeing any Objective-C / Cocoa-touch libraries for this though, so am assuming I will have to roll my own. (I saw the Seadragon Ajax component, which is pretty slick, but I'm dealing with collections here, which it doesn't support. I would also like to roll this as a native application just to get the experience.)
The only open source project I found for displaying/manipulating the tiled image sets was Openzoom - a Flash component. I'm not to familiar with ActionScript either (Python, Java, C#, and c are the only languages I have really used), but briefly inspecting the code I didn't really have any issues with it and can probably use it for hints on how to swap the tiles in and out, etc. But, as I'm pretty new to Objective-C/Cocoa-touch, some pointers in the right direction would be appreciated.
1) Are there any other projects out there I am missing, or is OpenZoom my best bet for some reference?
2) Should I be trying to do this display in the UIKit framework, or should I do it as an OpenGL display?
3) Any other suggestions/pointers that I didn't think to ask.

I have just been working on a few apps that rely on tiling large images to allow for deep zooming. I found a couple of examples but the best and most useful for me was Apple's "PhotoScroller" sample code.
It relies on CATiledLayer to handle the tiling. The result is an extremely smooth and responsive interface even with very large images and its not too complex. (A little complex but not too bad).
So to answer your question directly:
PhotoScroller Code
QuartzCore Framework (which is part of the SDK)
There is a great, free little mac app for slicing images into tiles that I use a lot: "Tilen"

In the WWDC 2010 source samples, under iOS, there is a project in the ScrollView Suite called Tiling. It corresponds to WWDC10 session 104. It is probably the best image tiling example out there.

You can take a look at they way RouteMe library does this, the dynamic loading of higher resolution tiles, panning, etc. https://github.com/route-me/route-me

I can't believe nobody has told you about UIScrollview; the UIScrollView component is designed for this very purpose! (think Google Maps, which uses it).
Check out the class reference...
UIScrollView
The delegate method you require is the following....
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
This allows you to check the zoom level, offset etc and then provide a view for zooming. This way you can maintain your 'position' within the tiled landscape independently of the graphics used to represent it.
Don't roll your own UIScrollView, no need to!

Take a look at CATiled Layer. See my answer to a similar question here: Drawing in CATiledLayer with CoreGraphics CGContextDrawImage

Related

Rendering a preview of a UIView in another UIView

I have a very intriguing obstacle to overcome. I am trying to display the live contents of a UIView in another, separate UIView.
What I am trying to accomplish is very similar to Mission Control in Mac OS X. In Mission Control, there are large views in the center, displaying the desktop or an application. Above that, there are small views that can be reorganized. These small views display a live preview of their corresponding app. The preview is instant, and the framerate is exact. Ultimately, I am trying to recreate this effect, as cheaply as possible.
I have tried many possible solutions, and the one shown here is as close as I have gotten. It works, however the - (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx method isn't called on every change. My solution was to call [cloneView setNeedsDisplay] using a CADisplayLink, so it is called on every screen refresh. It is very near my goal, but the framerate is extremely low. I think that [CALayer renderInContext:] is much too slow.
If it is possible to have two CALayers render the same source, that would be golden. However, I am not sure how to approach this. Luckily, this is simply a concept app and isn't destined for the App Store, so I can make use of the private APIs. I have looked into IOSurface and Quartz contexts, but I haven't been able to solve this puzzle so far. Any input would be greatly appreciated!
iOS and OSX are actually mostly the same underneath at the lowest level. (However, when you get higher up the stack iOS is actually largely more advanced than OSX as it is newer and had a fresh start)
However, in this case they both use the same thing (I believe). You'll notice something about Mission Control. It isolates "windows" rather than views. On iOS each UIWindow has a ".contentID" property and CALayerHost can use to make the render server share the render context between the 2 of them (2 layers that is).
So my advice is to make your views separate UIWindows and get native mirroring for free-(ish). (In my experience the CALayerHost takes over the target layers place with the render server and so if both the CALayerHost and the window are visible the window won't be anymore, only the layer host will be (which the way they are used on OSX and iOS isn't a problem).)
So if you are after true mirroring, 2 copies of it, you'll need to resort to the sort of thing you were thinking about.
1 Option for this is to create a UIView subclass that uses
https://github.com/yyfrankyy/iOS5.1-Framework-Headers/blob/master/UIKit.framework/UIView-Rendering.h#L12
this UIView private method to get an IOSurface for a target view and then using a CADisplayLink once per second get and draw the surface.
Another option which may work (I'm not sure as I don't know your setup or desired effect) is possibly just to use a CAReplicatorLayer which displays a mirror of a CALayer using the same backing store (very fast and efficient + public stable API).
Sorry I couldn't give you a fixed, "this is the answer reply", but hopefully I've given you enough ideas and possibilities to get started.
I've also included some links to things you might find useful to read.
What's the magic behind CAReplicatorLayer?
http://aptogo.co.uk/2011/08/no-fuss-reflections/
http://iphonedevwiki.net/index.php/SBAppContextHostManager
http://iphonedevwiki.net/index.php/SBAppContextHostView
http://iphonedevwiki.net/index.php/CALayerHost
http://iky1e.tumblr.com/post/33109276151/recreating-remote-views-ios5
http://iky1e.tumblr.com/post/14886675036/current-projects-understanding-ios-app-rendering

Create iphone interface from psd

For every developer arrives the day to improve the user interface experience because apps are evalutated mainly from the ui carefulness.
So, i've took a look around the websites and I found some psd where to start to desing my apps.
My question is: How to transform a psd prototype to a well-working app?
I don't unserstand how a mockup can help a developer to build a ui...
Can someone make me some clear the situation?
Well, I'd be careful to make a distinction between the graphics an app uses and the actual User Interface. Certainly the graphics are part of the UI, but the UI is soooo much more than that. Depending on how it is done, photoshop mock ups can be simple graphics you can use for your interface to complexes 'scenes' describing how the app functions. In the latter case, the mock-up can be useful for UI design, in the former case it just gives you pretty images to use (which can certainly be useful).
But to more directly answer your question, most people take 'slices' (individual pieces) of the photoshop image and export them as .png images (or .jpg). If the .psd file doesn't already have the images 'sliced', look up 'photoshop image slicing' on Google. You can then import them into Xcode and use them as background images for the controls you want to use. Especially since iOS 5.0, images can be used for a lot of controls. Also, you'll probably want to make sure you make the image resizable with proper UIEdgeInsets. This will allow the image to resize without pixilation by setting an area that can be tiled within the image.

support of Cocos2d-iphone for iPhone 4 high res

I'm trying to create a relatively simple game with 2D graphics which has somewhat complicated animations. I tried to develop the game with the basic Core Graphics and Core Animation libraries but the animation performance of the game objects is not satisfactory (i.e. jerky/delayed).
So, I am now looking into Cocos2D which looked very promising until I checked into the high resolution support for the iPhone 4. This doesn't seem to work very well at all, but then again, i've just started to look into it.
The one thing the documentation seems to say about the issue it so simply use the CCDirector to set the scale factor, which can be done like so:
if( [[UIScreen mainScreen] respondsToSelector:#selector(scale)]) {
[[CCDirector sharedDirector] setContentScaleFactor: [[UIScreen mainScreen] scale] ];
}
However, this doesn't give the behavior I expect. It simply doubles the amount of pixels to work with, meaning I have to take the 'double pixels factor' into account in all my code.
In the Core Graphics/Animation libraries the coordinate space we work with doesn't change. Behind the curtains it simply doubles everything to fill the iPhone 4 high res screen and uses the #2x images where available. This actually works very well and the game logic need not take the device's resolution into account. Cocos2D seems to have implemented this pretty badly, making me not want to go onboard the Cocos2D train.
I found some other topics on the subject but there were no real answers that didn't involve workarounds. Is this being fixed? Am I doing it wrong or is Cocos2D simply not high res ready? Are there any alternatives to Cocos2D which can give me what I need?
Sorry for the shameless self-promotion but I guess it can help you out. I've written two small blog posts on high res in cocos2d recently and put them up on our website.
The first one goes into detail as to how to get cocos2d up and running including a proposed fix for how to implement the auto-loading behaviour of regular vs high-res images.
Additionally, there is a second post trying to go into some details on the difference between points and pixels. UIKit is entirely based on points which is why you do not have to re-work all your coordinates. In contrast to UIKit, cocos2d works based on pixels and is therefore resolution-dependent. You can provide cocos2d with the means to work with points rather than pixels through some rather simple conversions. I've implemented those as categories for CCDirector and CCNode to make them easy to work with. Obviously, the methods in these categories are not the only ones one should "pointify". Specifying sizes on CCLabel or any positions on CCMoveBy, for example, are pixel-based and thus would have to be reworked also ...
Have a look at the blog at: http://apptech.next-munich.com/ (I would've directly linked to the articles but as a new user I can only post a single link in an answer).
Hope this helps and gets you started!
I'm in the process of figuring out a pretty simple solution to this. My progress is posted here: http://www.cocos2d-iphone.org/forum/topic/8511#post-50361
Basically you scale your the texture source rects in CCSprite, but nothing else, that way you get to use your same 320x480 coordinate system(aka a points system), but you get high res graphics.
You should combine my technique with this with point #2 from Benjamin's blog here, so you don't get memory problems: http://apptech.next-munich.com/2010/07/high-res-using-cocos2d-on-ios-4.html
Cocos2D uses the UIImage methods imageWithContentsOfFile: and initWithContentsOfFile: which, despite what the documentation says, don't correctly return the #2x versions of images when on the iPhone 4.
This is a known bug and apparently Apple are working on it.
However, some people believe this is correct behaviour as it is passing a path to a specific file, rather than a name of a file and letting the system decide which one to use. In that case, I have proposed that the documentation be updated to reflect this fact if it is true. We'll see how Apple respond.

Getting better at drawing in code for Cocoa?

What are some suggested "paths" for getting better at drawing in code in Cocoa? I think at this point, that's my biggest weakness. Is drawing in code something general, or Cocoa-specific?
Thanks!
- Jason
The best way is probably practice. Try drawing some simple things at first: a calendar (basically a grid), a custom button, or a digital clock.
Its also worth noting that a lot of 'custom' controls are made from images, so not that much of the drawing is done in code -- the only thing the code does is stitch those images together.
You might want to look at Opacity, a drawing app for OS X (I'm not affiliated with these folks, just discovered the app a few days ago). What sets Opacity apart from other drawing apps is that it can create Quartz code directly from your drawings. Naturally, the generated code is not perfect but in the few days I've been trying this app I've found it to be quite helpful in understanding how to use Quartz more effectively.
Drawing in code is need for creating custom controls no matter what UI toolkit you pick. Drawing in code certainly has its advantage, for example the application/framework that you are building is really lightweight come production time, cause there will be lot let resources(images/fonts/etc) to worry about.
Also if a problem arises changing drawing in code is a lot easier than to redo code and images together.
If you are doing Cocoa drawing start by looking at source code of BGHudAppKit and reading Cocoa Drawing Guide by Apple.
I'm in the same boat as you; I'd like to learn more about drawing code.
It's a big document, but the Quartz 2D programming guide on the developer website seems like a good place to start from. They introduce Graphics Contexts and Paths and include plenty of images.
There's also a book referenced in that document, Programming With Quartz: 2D and PDF Graphics in Mac OS X which looks good. The APIs for iPhone and OSX are almost identical, so there's no problem using a Mac OSX book.
So I'd suggest start with the Apple documentation (you don't need to read past the section on CGLayer drawing), try some sample code and figure out how it's working. Then move on to either that book or find more sample code on the web. Good luck!

Are tile overlays possible with the iPhone's MapKit

I already have a tile source set up for use with the Google Maps JavaScript API. I am trying to translate this for use with the iPhone MapKit. I have correctly implemented the javascript zooming levels into mapkit. Whenever - (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated is called, I snap the region to the nearest zoom level based on the same center point.
Is it possible to implement a solution possibly with CATiledLayer to implement a tiling solution. Does the iPhone use the standard 256x256 tiles like google maps does natively? Any direction or help on this would be greatly appreciated. I would rather not waste a couple weeks trying to implement this if it's not possible.
FWIW, I spent quite a bit of time looking for a decent solution… before diving into a CATiledLayer example, I noticed MKOverlay and MKOverlayView — which are new in iOS 4 and plug right into a MKMapView.
Couldn’t find a good example implementation of using MKOverlays that pull arbitrary image data (say, UIImages from a remote tile server), but I tinkered around with the API enough until I got it working.
Built a simple example implementation of it in case anyone (like me) wants a reference:
http://github.com/mtigas/iOS-MapLayerDemo
Hope this helps someone out in the future.
MapKit doesn't provide much in the way of custom tile sources (in fact, it provides absolutely nothing to customize sources: you either use Google Maps or you don't). I've been working with a similar problem myself, though, and I've found RouteMe to be a pretty good solution for custom maps: http://code.google.com/p/route-me/
Built-in support exists for OpenStreetMaps, OpenAerialMaps (which is currently offline), Virtual Earth, and Yahoo Maps, but the framework makes it pretty easy to plug in your own tile source, too.
Yes, since iOS 7, MKTileOverlay will do:
https://developer.apple.com/library/ios/documentation/MapKit/Reference/MKTileOverlay_class/Reference/Reference.html