I have an image captured every second from my web cam of size 720x576.
I ultimately display this in a canvas control via my server.
I convert this jpeg to bytes (31553) and upload it using WCF.
I have been debating whether to split this image into 4 smaller images and uploading them 1 after the other. When each image is uploaded it is drawn on a hidden canvas. Then once all 4 images are uploaded I update the visible canvas with the 'cached' canvas.
Will this be a better/faster way to upload the image by splitting into 4 images or will it make no difference at all?
I will write and conduct tests for this code now but thought I would set myself up to be educated as to what the done/accepted wisdom is.
Thanks
If you look from compression point of view, the total size of the four images should be more than one image. You can imagine as compressing redundant information 4 times. If you keep on dividing and compressing, you may end up sending every pixel.
Another way to look at this is from network's point of view. Many times internet bandwidth is the limiting factor, so probably sending one file would be best (as it would be smaller). In another scenario, there might be congestion in the network so multiple data streams (if you upload them in parallel and the server is multi-threaded) are more likely to get a larger chunk of the bandwidth.
Related
I looked into inverse kinematics as a way of using animation, but overall thought I might want to proceed with using sprite texture atlases to create animation instead. The only thing is i'm concerned about size..
I wanted to ask for some help in the "overall global solution":
I will have 100 monsters. Each has 25 frames of animation for an attack, idle, and spawning animation. Thus 75 frames in total per monster.
I'd imagine I want to do 3x, 2x and 1x animations so that means even more frames (75 x 3 images per monster). Unless I do pdf vectors then it's just one size.
Is this approach just too much in terms of size? 25 frames of animation alone was 4MB on the hard disk, but i'm not sure what happens in terms of compression when you load that into the Xcode and texture atlas.
Does anyone know if this approach i'm embarking on will take up a lot of space and potentially be a poor decision long term if I want even more monsters (right now I only have a few monsters and other images and i'm already up to ~150MB when I go to the app on the phone and look at it's storage - so it's hard to tell what would happen in the long term with way more monsters but I feel like it would be prohibitively large like 4GB+).
To me, this sounds like the wrong approach, and yet everywhere I read, they encourage using sprites and atlases accordingly. What am I doing wrong? too many frames of animation? too many monsters?
Thanks!
So, you are correct that you will run into a problem. In general, the tutorials you find online simply ignore this issue of download side and memory use on device. When building a real game you will need to consider total download size and the amount of memory on the actual device when rendering multiple animations at the same time on screen. There are 3 approaches, just store everything as PNG, make use of an animation format that compresses better than PNG, or third you can encode things as H264. Each of these approaches has issues. If you would like to take a look at my solution to the memory use issue at runtime, have a peek at SpriteKitFireAnimation link at this question. If you want to roll your own approach with H264, you can get lots of compression but you will have issues with alpha channel support. The lazy thing to do is use PNGs, it will work and support alpha channel, but PNGs will bloat your app and runtime memory use is heavy.
I am planning to ship an app with at least 20 pictures that can be at big as 10mb each. They are pictures that the user is likely to zoom in quite a bit therefore it is a requirement to keep the resolution quite high. We are still trying to make them smaller, but even so, its unlikely that they are going to be less than 7mb each.
The images can be shipped with the app as well as additional pictures can also be downloaded. The requirement is for the pictures to be available offline once the user downloads them as the app is to be used in remote areas by researchers.
What is the best mechanism to store them and how should I store them in iOS Swift 3?
Thanks for your help in advance.
You can store your pictures in document directory of the app and store the path in SQLite DB.
There are not rules but a set of best practices.
To store them I suggest you to save them directly into your resources, not Xcode image asset, this is because "image asset" can only be called with the imageNamed: method of UIImage, that has the side effect of cache images.
Then you can create a plist file with an array of image names, and fetch your info from here. If you need something more complicated there is Core Data, but I can't see an application of it with your spec.
What is the size of an uncompressed image in memory? An approx
equation n_pixel_height * n_pixel_width * n_channels in bytes (supposing 8 bit for channel)
If your images are about 10Mb in jpg they are compressed, thus means that they will take a huge amount of memory. memory on this kind of devices is a precious and short resource.
If your app exceeds the memory limit, after a set of callback such as didReceiveMemoryWarning, if you don't free enough memory, you app will be killed.
Alway try on device in this case and not on simulator because the simulator use your mac resources.
Now how to handle big images?
You can use CATiledLayer, you can find a lot of tutorials online. CATiledLayer as the name suggest creates a tiles of layer, each tile should correspond at a piece of your image, and it draws them only when they are visible.
Unfortunately it draws asynchronously this means that your tiles can be shown not exactly at the same time, there some strategy to avoid that issue, one is explained in an apple sample code.
Of course there is a problem that needs to be solved, how can I cut my large images into tiles?
You can do programmatically or provide them already cut as resources of your application
I'm working on an iPad-only iOS app that essentially downloads large, high quality images (JPEG) from Dropbox and shows the selected image in a UIScrollView and UIImageView, allowing the user to zoom and pan the image.
The app is mainly used for showing the images to potential clients who are interested in buying them as framed prints. The way it works is that the image is first shown, zoomed and panned to show the potential client if they like the image. If they do like it, they can decide if they want to crop a specific area (while keeping to specific aspect ratios/sizes) and the final image (cropped or not) is then sent as an email attachment to production.
The problem I've been facing for a while now, is that even though the app will only be running on new iPads (ie. more memory etc.), I'm unable to find a method of handling the images so that the app doesn't get a memory warning and then crash.
Most of the images are sized 4256x2832, which brings the memory usage to at least 40MB per image. While I'm only displaying one image at a time, image cropping (which is the main memory/crash problem at the moment) is creating a new cropped image, which in turn momentarily bumps the apps total RAM usage to about 120MB, causing a crash.
So in short: I'm looking for a way to manage very large images, have the ability to crop them and after cropping still have enough memory to send them as email attachments.
I've been thinking about implementing a singleton image manager, which all the views would use and it would only contain one big image at a time, but I'm not sure if that's the right way to go, or even if it'd help in any way.
One way to deal with this is to tile the image. You can save the large decompressed image to "disk" as a series of tiles, and as the user pans around pull out only the tiles you need to actually display. You only ever need 1 tile in memory at a time because you draw it to the screen, then throw it out and load the next tile. (You'll probably want to cache the visible tiles in memory, but that's an implementation detail. Even having the whole image as tiles may relieve memory pressure as you don't need one large contiguous block.) This is how applications like Photoshop deal with this situation.
I ended up sort of solving the problem. Since I couldn't resize the original files in Dropbox (the client has their reasons), I went ahead and used BOSImageResizeOperation, which is essentially just a fast, thread-safe library for quickly resizing images.
Using this library, I noticed that images that previously took 40-60MB of memory per image, now only seemed to take roughly half that. Additionally, the resizing is so quick that the original image gets released from memory so fast, that iOS doesn't execute a memory warning.
With this, I've gotten further with the app and I appreciate all the idea, suggestions and comments. I'm hoping this will get the app done and I can get as far away from large image handling as possible, heh.
I want to allow the user to select a photo, without limiting the size, and then edit it.
My idea is to create a thumbnail of the large photo with the same size as the screen for editing, and then, when the editing is finished, use the large photo to make the same edit that was performed on the thumbnail.
When I use UIGraphicsBeginImageContext to create a thumbnail image, it will cause a memory issue.
I know it's hard to edit the whole large image directly due to hardware limits, so I want to know if there is a way I can downsample the large image to less then 2048*2048 wihout memory issues?
I found that there is a BitmapFactory Class which has an inSampleSize option which can downsample a photo in Android platform. How can this be done on iOS?
You need to handle the image loading using UIImage which doesn't actually load the image into memory and then create a bitmap context at the size of the resulting image that you want (so this will be the amount of memory used). Then you need to iterate a number of times drawing tiles from the original image (this is where parts of the image data are loaded into memory) using CGImageCreateWithImageInRect into the destination context using CGContextDrawImage.
See this sample code from Apple.
Large images don't fit in memory. So loading them into memory to then resize them doesn't work.
To work with very large images you have to tile them. Lots of solutions out there already for example see if this can solve your problem:
https://github.com/dhoerl/PhotoScrollerNetwork
I implemented my own custom solution but that was specific to our environment where we had an image tiler running server side already & I could just request specific tiles of large images (madea server, it's really cool)
The reason tiling works is that basically you only ever keep the visible pixels in memory, and there isn't that many of those. All tiles not currently visible are factored out to the disk cache, or flash memory cache as it were.
Take a look at this work by Trevor Harmon. It improved my app's performance.I believe it will work for you too.
https://github.com/coryalder/UIImage_Resize
I have a Flash file that I need to reduce the size of.
The reason that I need to reduce its size is that I will need to convert this into an iPhone app.
currently it only has 2 buttons and 2 TLF textfileds on the stage one, layer one and the size of the file is 355KB.
I have also placed the code on layer 2.
is there anyway to reduce the size of it so I won't have problems when publishing and sending for app store?
Thanks
The biggest portion of that file size will be related to TLF. TLF (Text-Layout-Framework) is huge and is generally not recommended on mobile (as it has pretty high cpu usage).
If you're not using any TLF specific features, then it would be wise to change your text fields to use classic text instead (DF3).
Beyond TLF, make sure you're using vector objects instead of bitmaps wherever you can as that will drastically reduce file size. If you are using bitmaps, you can play around with the compression settings to optimize file size further. You can do this globally in the Publish Settings (JPEG Quality) or individually on a graphics properties menu.
One note with Vector graphics and mobile, simple vectors will run ok, but complex vectors will run terribly. Make sure to set cacheAsBitmap = true; on any complex (or even all) vectors to improve performance. OR in FLashPRO, click on a movieClip and in the properties panel, go to the "Display" twirl down, and set cache as bitmap in the Render setting.