Android has a nice way of defining stretchable images called a nine-patch. See these docs for a description of the concept. The idea is to surround a png image with a 1-pixel border where you can define the stretchable areas and the padding dimensions of the image. This is absolutely brilliant and I'd like to use the idea in my iPhone app. Before writing my own nine-patch to UIImage loader I thought I'd see if one already exists. Google doesn't return any results so I don't have much hope, but it doesn't hurt to ask, right? :-)
EDIT: Folks, I appreciate the answers but I know about stretchableImageWithLeftCapWidth.... I'm looking for code that takes a path #"foo.9.png" and returns a stretchable UIImage. This code will undoubtedly use stretchableImageWithLeftCapWidth... internally. I'm sure I could write the code myself using that method. But I'm asking if somebody else has already done it.
I received an e-mail from Tortuga22 software who informed me that they have created such a library and released it under the Apache license:
Announcement: http://blog.tortuga22.com/2010/05/31/announcing-tortuga-22-ninepatch/
Source code: http://github.com/tortuga22/Tortuga22-NinePatch
Example usage:
// loads-and-caches ninepatch and rendered image of requested size
UIImage buttonImg = [TUNinePatchCache imageOfSize:buttonSize
forNinePatchNamed:#"buttonNormalBackground"];
[self.buttonNeedingBackground setImage:buttonImg
forControlState:UIControlStateNormal];
Also look at UIView's contentStretch property. It is more robust and well-behaved than stretchableImageWithLeftCapWidth. Basically, it works by just defining the stretchable rectangle within your image and automatically creating a scaled nine-patch. This internal rectangle can be anything - it doesn't even have to be in the center of the image. Plus unlike stretchableImage this method will properly shrink graphics and behave as expected for graphics with lighting or gloss. I can't think of any real-world application where you would want more than this.
Yes UIImage does support something like it. See
- (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight and the documentation for leftCapWidth and topCapHeight
basically the image is not stretched in the area leftCapWidth pixels from the left and right edge and topCapHeight pixels from the top and the bottom. When the image is scaled the area inside of these limits is subject to stretching.
All UIImage images support this natively. By default the entire images is stretchable, but you can set caps with the leftCapWidth and topCapHeight properties or you can generate one from an existing UIImage with the - (UIImage *)stretchableImageWithLeftCapWidth:(NSInteger)leftCapWidth topCapHeight:(NSInteger)topCapHeight method.
Do note that in apple's implementation, when you set one or both of these values, the stretchable area is forced to be a single pixel high/wide.
Related
I need the code to add invisible watermark to another image in Android
As the comments mentioned, Stackoverflow isn't a free coding service. I will provide you with a high level design advice from which you can implement your own code.
Invisible watermark could just be metadata. The point is to make your particular photo unique and identifiable, right? I would recommend you looking into image metadata manipulation for a simple solution.
That being said, if you are looking for some high tech stealthy watermarking, then you might be looking for pixel manipulation. You can change a few of the pixel colors so if it's compared with the original image with the naked eye, it looks identical but if compared with their base64 encoding you can see a difference. Simply create your own pattern as some sort of signature to attach to images to identify them.
Both method allows you to determine if an image is yours due to the "watermark" you leave on it.
VectorDrawable is a new feature for Android after API Level 21, Which add support for vectorgraph. But I have a question for VectorDrawable, is it suitable for me to replace most of images in my project to VectorDrawable. In the android offical dev site I saw a few words :
A vector drawable is appropriate for simple icons. The material icons provide good examples of the types of images that work well as vector drawables in an app. In contrast, many app launch icons do have many details, so they work better as raster images.
Is that means VectorDrawable is only appropriate for simple icons like offical material icons, images have many details aren't appropriate to use VectorDrawable.
Sorry for my poor english skills, hope you guys can understand me! 😬
I plan to use VectorDrawable for all my project image resource if it is ok.
You're basically right.
Vector images describe shapes and geometry, and need to be rendered into bitmaps (a grid of pixels). This requires some math, calculating the pixels that represent the lines and curves defined by the icon.
The more complicated an icon gets, means the more shapes that are required, and the more calculations that need to be done.
On the other side, if you already have the icon rendered to a specific scale, like with png images, all of the pixel values have already been calculated. Now it just needs to be converted to a bitmap and scaled to the size it gets displayed at.
So depending on the situation, an icon may be able to decode and scale from a png file faster than rendering from a vector drawable, or vice versa, it all depends on the icon.
It's hard to say exactly how simple an icon needs to be, so try it out and make sure it runs well on a range of devices.
I'm new to Android Graphics and would appreciate if you can advise an algorithm to color particular part of image with outlines. I would like to create similar to this application.
I should be able to fill in parts of the image with colors, or use freehand tool to paint, but it should not go outside the outlines.
Should I use any image recognition tools to track black pixels for example?
I can also use predefined images only. I know I can convert each part of it into vector format. Will it be helpful?
Any tutorial references or example code would be highly appreciated.
You could look for connected-component-labeling. It basically assigns a label to each pixel where the label depends on the color of the neighbour. A description and implementation (though not in Java) can be found here: http://www.codeproject.com/Articles/336915/Connected-Component-Labeling-Algorithm. An implementation in java might be found here (https://github.com/klonikar/connected-components-labeling). I didn't check it though.
When you selected the pixels that you need, you can color them as described here: how to change the color of certain pixels in bitmap android
Is it possible in Android to use the Vector images (for example, contours made in Adobe Illustrator) to be drawn on Canvas?
I looked at Vector graphics in Android but I don't want to use any additional third-party libraries.
So, is there any another way to make this idea?
One thought, that came to mind, was to convert to the 9patch images. But still I'm not sure whether it sounds good.
All of fuss just over the aim to make the complex countour from which I want to create android.graphics.Path using public void addPath (Path src, Matrix matrix) function.
You cannot use vector images in Android, at least with the built in SDK.
It may exist libraries to use vector images, but this is not the Android best practice.
What you need to do in order of not pixelating/blurring your images is to use the different drawable folders existing in android.
You should provide different images depending on the screen density of the display, and android will pick the correct one in runtime.
http://developer.android.com/guide/practices/screens_support.html
9 patches are good only if the image is meant to stretch to fit its content, while its borders should repeat following a pattern. The typical use of this are buttons. For images that dont work as the background of a View, 9 patches are not a good option.
I'm having trouble cleanly down-scaling images on Android. I'm looking to scale small PNG images between arbitrary sizes of about 10-100% of their original size.
I've created a sample image to demonstrate the problem and exacerbate the unusual behaviors I'm seeing in Android's image scaler:
The above image is a screenshot from an Android device with some annotations added. I've also added the same images in a second column on the left side showing how they are rendered with a linear scaling by "The GIMP" (GNU Image Manipulation Program).
The base image consists of a checkerboard pattern background of red and blue pixels. On that background I've drawn some 1px-wide yellow lines and fairly thin green text. The image is 288x288 pixels.
When scaling the image to 1/3 of its original dimensions, Android seems to simply grab one in nine pixels, throwing out all other data. Some of the yellow lines disappear entirely as a result. Remarkably, the checkerboard pattern remains intact (which is simply a result of every 3rd pixel being used).
When scaling the image to a dimension of near-but-not-exactly 50% of its original size, e.g., 142x142 or 143x143, the scaler creates some fairly large anomalies/artifacts on the image.
At 50% size (144x144), the image looks correct.
The test image does bring out the worst of the image scaler, but "normal" PNG icon images are severely impacted as well. From 10-33% or so the images aren't properly resampled, and thus appear extremely "bitmapped". And certain larger size images have very strange anomalies in them at certain sizes.
If anyone knows a means to disable this strange scaling behavior, even at a performance cost, I'd greatly appreciate knowing about it. It can certainly be solved by writing an algorithm that works directly on the pixels of bitmaps, but I'm hopeful that isn't the only option.
Also noteworthy is the fact that all image work is being done with ARGB_8888 Bitmap.Configs. I've tried manipulating image size by setting maxwidth/maxheight on ImageViews, by using Bitmap.createScaledBitmap(), and by using Bitmap.createBitmap with a Matrix. All attempts have this same result. Bitmap filtering is enabled.
Thanks again for any suggestions!
Using Bitmap.createScaledBitmap() and Bitmap.createBitmap with a Matrix is the same; see the source for Bitmap.createScaledBitmap (which hasn't changed since Android 2).
On Android 4.0+, using a matrix (as in Bitmap.createScaledBitmap) allows hardware-accelerated operations if enabled (enabled by default on 4.1+ IIRC), thus we doesn't have direct control over what is being done and how it is done.
That means you'll have to implement your own scaling method using the desired (here, linear) filtering; either by pixel processing; or using OpenGL ES with the good filter, but it may not be available on all devices.