GPUImage: to use or not to use smoothlyScaleOutput - iphone

I am using GPUImage for applying filters in my app (using it to apply one value filters to still photos). I'm trying to decide if I need to use smoothlyScaleOutput or not. The downside of it is it takes a long time to load large photos. I've read Brad Larson say:
The smoothlyScaleOutput: option for a photo tells the framework to use
trilinear filtering when downsampling the photo. That is, for large
photos that you're shrinking down, it will produce a much smoother
output. If you don't need to shrink a photo, you can turn that off for
better performance and a slightly sharper picture.
Just curious but for those out there who've used GPUImage in the same fashion that I am, is it worth it for me to enable this option? It's hard for me to tell the difference, but I've only sampled a handful of photos using some of the basic filters (brightness, contrast, sepia, etc.).
Also was confused about what might constitute shrinking a photo. Would that mean using UIImage drawInRect to draw the photo at a smaller resolution? Or would that mean taking a large photo and transforming its size to fit in a UIImageView? Or both?
Any help would be appreciated thanks.

Related

CoreML Image Detection

I want to implement an application, that is able to recognize pictures from camera input. I don't mean classification of objects, but rather detecting the exact single image from given set of images. So if I for example have an album with 500 pictures, then if I point a camera to one of them, then application will be able to tell it's filename. Most of tutorials I find about CoreML is strictly for image classification (recognizing class of object) and not about recognizing exact image name in camera. This needs to work from different angles as well, and all I can have for training the network is this album with many different pictures (single picture for single object). Can this be somehow achieved? I can't use ARKit Image Tracking, because there will be about 500 of these images, and I need to find at least a list of similar ones first with CoreML / Vision.
I am not sure, but I guess perceptual hashing might be able to help you.
It works in a way that it makes some fingerprint from the reference images, and for a given image, it extracts the fingerprints as well, and then you can find the most similar fingerprints.
in this way, even if the new image is not 100% as the image in the dataset, you still can detect it.
It is actually not very hard to implement. but if you would like, i think phash library is a good one to use.

HUGE image to show on the iPhone

Ok, here's my problem. I have a HUGE jpg file, 18000 x 18000 pixels 41MB in size.
If you really need to know, it's a map of a section of the country with services.
My project is really simple. I just need to be able to zoom and display this granddaddy size image. All the way from aspect fit to 100% on the iPhone. I'm not too sure if this can be done or how long it will take. Would appreciate any insights.
I have tried using imageView but I read that it really shouldnt exceed 1024 x 1024. That is way below what I have. If you have an idea how to go about doing this, please share!
You should split the image into tiles, at a range of magnifications. Calculate and build these off-line, and ship them as individual files in the app bundle. Given the zoom in your display, pick the closest zoom size. You then select which tiles are needed to cover the screen, and make a grid of them. As the user zooms, select the appropriate tile size.
The benefit of this is that you don't ever have to load HUGE files into memory, only as much as needed.
This is how Google maps does it.
Can't give you any code, sorry!
You should follow an approach similar to what Google Maps and other map sites do. You need to slice the whole map in sections, so the users don't need to load the whole map if it's not always necessary (plus makes loading time way faster)
There's a couple of solutions that might work for you like OpenLayers or even creating a Custom Google Map with your images as seen here and here
Here is an example from Apple for processing large images called PhotoScroller. The images have already been tiled. If you need an example of tiling an image in Cocoa check out cimgf.com

Fake long exposure on iOS

I have to implement long exposure photo capabilities to an app. Since i know that this is not really possible i have to fake it. It should work like "Slow Shutter" or "Magic Shutter".
Sadly i got no clue how to achieve this. I know how to take images with the camera (through AVFoundation) but i'm stuck at merging them to fake long shutter times.
Possibly i need to manipulate and combine all the images with coregraphics but i'm not sure about this (even the how). Maybe there's a better solution to this.
I would appreciate every help i can get here,
thank you people!
You might try the plus lighter blend mode.
Well, I suppose it would be possible to average together the results of several shots. I've mucked around a bit with the core graphics stuff to resize images (averaging together adjacent pixels), but with lower res images. The algorithm I used is here -- maybe it'll give you some ideas.
There may, of course, be a better way, and some tricks for working efficiently with high-res images. Can't help you there.
Convert the images to pixel bitmaps. Align and stack the bitmaps. Then try applying various 3D convolution filters to the 3D pixel array.

Is there a way to quickly modify individual color values in an image?

For example, I have a CGImageRef and I want to shift all pixels which are red to orange. Or to put it in other words: I want to apply a value function on every pixel in an image, which modifies the pixel based on the RGBA values it has. So the value function would calculate the new component values for that pixel based on the current component values and some algorithm applied to it.
I know how I could code that by hand with about 100 lines of code, but I wonder if there is a easier and maybe even faster way?
I believe Brad Larson has mentioned somewhere that things like this can be done on the GPU easily and fast. However, I must support iOS 3.2 so it should not get too fancy.
Would be happy about any ideas.
Thanks!
As far as I know there are no built in functions to achieve what you want.
The easiest way to get GPU acceleration when doing custom image manipulations on the pixel level is using the Accelerate.framework. Accelerate will use the 'best execution path' based on available hardware.
However... the port to iOS was only done for iOS4
(disclaimer: I have little to no experience nor knowledge of everything that's possible in OpenGL, so take my answer as limited within the Core Graphics realms of iOS)

Performance-wise: A lot of small PNGs or one large PNG?

Developing a simple game for the iPhone, what gives a better performance?
Using a lot of small (10x10 to 30x30 pixels) PNGs for my UIViews' backgrounds.
Using one large PNG and clipping to the bounds of my UIViews.
My thought is that the first technique requires less memory per individual UIView, but complicates how the iPhone handles the large amount of images, as it tries to combine the images into a larger texture or tries to switch between all the small textures a lot.
The second technique, on the other hand, gives the iPhone the opportunity to handle just one large PNG, but unnessicarily increases the image weight every UIView has to carry.
Am I right about the iPhone's attempts, handling the images the way I described it?
So, what is the way to go?
Seeing the answers thus far, there is still doubt. There seems to be a trade-off with two parameters: Complexity and CPU-intensive coding. What would be my tipping point for deciding what technique to use?
If you end up referring back to the same CGImageRef (for example by sharing a UIImage *), the image won't be loaded multiple times by the different views. This is the technique used by the videowall Core Animation demo at the WWDC 07 keynote. That's OSX code, but UIViews are very similar to CALayers.
The way Core Graphics handles images (from my observation anyway) is heavily tweaked for just-in-time loading and aggressive releasing when memory is tight.
Using a large image you could end up loading the image at draw time if the memory for the decoded image that CGImageRef points to has been reclaimed by the system.
What makes a difference is not how many images you have, but how often the UIKit traverses your code.
Both UIViews and Core Animation CALayers will only repaint if you ask them to (-setNeedsDisplay), and the bottleneck usually is your code plus transferring the rendered content into a texture for the graphics chip.
So my advice is to think your UIView layout in a way that allows portions that change together to be updated all at the same time, which turn into a single texture upload.
One large image mainly gives you more work and more headaches. It's harder to maintain but is probably less ram intensive because there is only one structure + data in memory instead of many structures + data. (though probably not enough to notice).
Looking at the contents of .app bundles on regular Mac OS, it seems the generally approved method of storage is one file/resource per image.
Ofcourse, this is assuming you're not getting the image resources from the web, where the bottleneck would be in http and its specified maximum of two concurrent requests.
One large gives you better performance. (Of cause if you should render all pictures anyway).
One large image will remove any overhead associated with opening and manipulating many images in memory.
I would say there is no authoritative answer to this question. A single large image cuts down (slow) flash access and gets the decode done in one go but a lot of smaller images give you better control over what processing happens when... but it's memory hungry and you do have to slice that image up or mask it.
You will have to implement one solution and test it. If it isn't fast enough and you can't optimise, implement the other. I suggest implementing the version which you personally find easier to imagine implementing because that will be easiest to implement.