It often happens that we want to load and display images to improve the functionality of our applications. In this article we'll take a quick peek at how images are loaded and displayed.
Image Display
At the risk of corrupting our thinking and falling back to the "old days" of web development, let's suppose that we want to build a header for our application. That is we want to load and display an image across the top of the window. In the "5-View Liquid" article we looked into how we might use views to lay out sections of our application, here we'll look at attaching an image to one such view. So let's get started. The code and cup of cappuccino image are attached in the "Graphics1.zip" file. Make sure the image is in the "Resources" subdirectory your application (the zip file has it that way).
The AppController.j looks like this:
The magic happens in lines 12 through 14 lo let's look at them in a little more detail. Cappuccino provides a nice way to locate resources (images and such) the CPBundle. We'll use that to get the location from which the application was started. We use the "pathForResource" method to get, you know, the path for the resource directory. That's why we put the image there. So lines 12 and 13 get the path to the image we're loading. Line 14 loads the image into memory - but it does not display it. One quick note: The "initWithContentsOfFile:size" expects the image size to be provided. There is an "initWithContentsOfFile" (without the size parameter) but it does not yet work correctly. This has been reported and a fix is no doubt on the way. For now just stick to using the sized version.
So how do we get the image to display? We have to put it into a "CPImageView" of course. In line 16 we build such an object then set a couple of parameters of it. The image shadow is actually a rather nice effect, but for this use we'll do without it so we set "has shadow" to no. We also don't want the image to be rescaled to fit the view, so we set the image scaling to CPScaleNone (line 18). Then we just associate the image with the image view (line 19) and add it to our application's view (line 21). Just so we can see where the boundaries are we've set the ImageView background to light grey. Running the code you should see exactly what is shown in the image above.
Image Alignment
In the code above associated an image with the image view. That allows the image to be displayed but you'll notice the image is stuck in the middle of the view. That may be what you intended but in some circumstances it would be nice to be able to control its placement. Unfortunately there doesn't appear to be any way to do that directly with the CPImageView. Instead we'll have to embed the image/image view into another view. We can do it this way (grab the AppController.j file from the Graphics2.zip attachment):
What have we done here? Well, skip over the boilerplate code and the "cleaning up" where we use variables to hold the image size, and look at lines 21 through 32. The first part of it (lines 21 through 23) set up the "wrapper" view that we'll use to contain the CPImageView that holds our image. We set it up to cover the entire width of the window and to have the same height as the image. We also set it to resize as the window resizes (line 23) so it always spans the window. As before, we create the image view, this time with a size the same as the image, and associate the image with it. Then we set the image view's resizing flag to "CPViewMinXMargin" (line 30) so the image sticks to the right-hand edge of the wrapper. When we're done we have an image that continues to stay at the right-hand side of the window, but is contained in a CPView that spans the entire window. Much like the header region of our 5-view layout note.
Custom View Class
In keeping with good (or at least better) design, let's move some of the image view layout functionality to its own class. Grab the "Graphics3.zip" file from the attachments and uncompress it. Inside you will find AppController.j and ImageDisplayView.j. Let's just look at the ImageDisplayView class:
Notice we've created a type of CPView with a new initialization function "initWithFrame:image:alignment:" which, as you can guess, will create a view with the specified frame, create an internal image view associated with the specified image, and align the image as indicated by the alignment parameter. The bulk of this initialization routine (lines 20 through 24) is just what we've seen before. Lines 26 through 33 just set the alignment of the internal image based on the input parameter. The input alignment is expected to be one of the global variables defined in lines 4 and 5. Just as an example usage, we can create an ImageDisplayView with a call like:
var view = [[ImageDisplayView alloc] initWithFrame:CGRectMake(0, 0, CPRectGetWidth(bounds), imageHeight)
image:image alignment:ImageDisplayViewlignRight];
See the attached code (Graphics3.zip) for the context of that instantiation.
We can no doubt extend the ImageDisplayView class to include vertical alignments, gaining access to the internal image (CPImageView), etc. Hopefully this gives you a nice starting point though.



Article Sections 

