I'm tring to download an image from the net, and to convert it to ninepatch format, how I select the stretchable pixels is out of scope for this thread.
I'm trying to use gist solution but I couldn't get it to work.
This is the source code:
NinePatchDrawable np = createNinePathWithCapInsets(res, bitmap, top,left, bitmap.getWidth() - right, bitmap.getHeight() - bottom, null);
and to get the resulted bitmap:
Bitmap outputBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(outputBitmap);
//np.setBounds(0, 0, width, height);
np.draw(canvas);
canvas.drawBitmap(outputBitmap, width, height, new Paint());
The returned bitmap doesn't contain the source bitmap and looks just like 4 segmentations(rect seg').
I could find any other to achive that goal, even not using OpenGL
The resulted image is:
try this:
public static byte[] getChunk(int xs, int xe, int ys, int ye) {
ByteBuffer b = ByteBuffer.allocate(84).order(ByteOrder.nativeOrder());
b.put((byte) 1); // wasDeserialized
b.put((byte) 2); // numXDivs
b.put((byte) 2); // numYDivs
b.put((byte) 9); // numColors
b.putInt(0); // UNKNOWN
b.putInt(0); // UNKNOWN
b.putInt(0); // paddingLeft
b.putInt(0); // paddingRight
b.putInt(0); // paddingTop
b.putInt(0); // paddingBottom
b.putInt(0); // UNKNOWN
b.putInt(xs); // segX start
b.putInt(xe); // segX end
b.putInt(ys); // segY start
b.putInt(ye); // segY end
for (int i = 0; i < 9; i++) {
b.putInt(1); // NO_COLOR
}
return b.array();
}
you can use it in NinePatchDrawable constructor (Bitmap, byte[], Rect, String)
Related
I have been struggling to get the preview of a PDF in the Android Print Framework to match the print output. However, I am able to get the output to match as a bitmap. However, if I scale the bitmap and put whitespace around the bitmap, the Print Framework crops out the whitespace. So, to prevent that from happening, I would like to draw a thin border around the edge of the entire Canvas.
This is the code that I have to scale the bitmap:
public static Bitmap captureScreen(View v) {
Bitmap screenshot = null;
Bitmap output = null;
try {
if (v != null) {
screenshot = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
int width = screenshot.getWidth();
int height = screenshot.getHeight();
int scaledWidth = (int) (width * 0.5);
int scaledHeight = (int) (height * 0.5);
output = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Bitmap scaled = Bitmap.createScaledBitmap(screenshot, scaledWidth, scaledHeight, false);
Canvas canvas = new Canvas(output);
Paint paint = new Paint();
int distX = (width - scaledWidth) / 2;
int distY = (height - scaledHeight) / 2;
canvas.drawBitmap(scaled, distX, distY, paint);
v.draw(canvas);
}
} catch (Exception e) {
Log.d("ScreenShotActivity", "Failed to capture screenshot because:" + e.getMessage());
}
return output;
}
I would like to draw a thin black border around the entire canvas for I can prevent the whitespace from being cropped out by the Print Framework.
Well, you have the width and height of the canvas, just call Canvas.drawRect(0, 0, width - 1, height - 1, strokePaint)?
I'm currently in the process of porting an existing iOS app over to Android and have run into a snag where I need to crop the contents of a view in my layout.
In iOS I was simply accessing the layer of the view and then setting layer.contentsRect accordingly.
In Android, I thought I had found an equivalent function of the GLSurfaceView class - setClipBounds, but this only works on devices with support for API level 18 and throws a NoSuchMethodError exception on my Galaxy S 3.
Does anyone have an alternative solution (or support library) for clipping or cropping the view contents for API level 9 (2.3)? Thanks.
here's some cropping code i wrote in xamarin (c#) it was ported from Java, you'll need to do the conversion on your own, the class names are roughly the same and the methods and properties are exposed as get/set in Java.
the code crops a bitmap to a circle, similar to facebook floating faces :)
public static class BitmapHelpers
{
public static Bitmap LoadAndResizeBitmap (this string fileName, int width, int height)
{
// First we get the the dimensions of the file on disk
BitmapFactory.Options options = new BitmapFactory.Options { InJustDecodeBounds = true };
BitmapFactory.DecodeFile (fileName, options);
// Next we calculate the ratio that we need to resize the image by
// in order to fit the requested dimensions.
int outHeight = options.OutHeight;
int outWidth = options.OutWidth;
int inSampleSize = 1;
if (outHeight > height || outWidth > width) {
inSampleSize = outWidth > outHeight
? outHeight / height
: outWidth / width;
}
// Now we will load the image and have BitmapFactory resize it for us.
options.InSampleSize = inSampleSize;
options.InJustDecodeBounds = false;
Bitmap resizedBitmap = BitmapFactory.DecodeFile (fileName, options);
return resizedBitmap;
}
public static Bitmap GetCroppedBitmap (Bitmap bitmap)
{
Bitmap output = Bitmap.CreateBitmap (bitmap.Width,
bitmap.Height, global::Android.Graphics.Bitmap.Config.Argb8888);
Canvas canvas = new Canvas (output);
int color = -1;
Paint paint = new Paint ();
Rect rect = new Rect (0, 0, bitmap.Width, bitmap.Height);
paint.AntiAlias = true;
canvas.DrawARGB (0, 0, 0, 0);
paint.Color = Color.White;
canvas.DrawCircle (bitmap.Width / 2, bitmap.Height / 2,
bitmap.Width / 2, paint);
paint.SetXfermode (new PorterDuffXfermode (global::Android.Graphics.PorterDuff.Mode.SrcIn));
canvas.DrawBitmap (bitmap, rect, rect, paint);
return output;
}
}
I have images which I display in my app. They are downloaded from the web. These images are pictures of objects on an almost-white background. I want this background to be white (#FFFFFF). I figure, if I look at pixel 0,0 (which should always be off-white), I can get the color value and replace every pixel in the image having that value with white.
This question has been asked before and the answer seems to be this:
int intOldColor = bmpOldBitmap.getPixel(0,0);
Bitmap bmpNewBitmap = Bitmap.createBitmap(bmpOldBitmap.getWidth(), bmpOldBitmap.getHeight(), Bitmap.Config.RGB_565);
Canvas c = new Canvas(bmpNewBitmap);
Paint paint = new Paint();
ColorFilter filter = new LightingColorFilter(intOldColor, Color.WHITE);
paint.setColorFilter(filter);
c.drawBitmap(bmpOriginal, 0, 0, paint);
However, this isn't working.
After running this code, the entire image seems to be the color I was wanting to remove. As in, the entire image is 1 solid color now.
I was also hoping to not have to loop through every pixel in the entire image.
Any ideas?
Here is a method I created for you to replace a specific color for the one you want. Note that all the pixels will get scanned on the Bitmap and only the ones that are equal will be replaced for the one you want.
private Bitmap changeColor(Bitmap src, int colorToReplace, int colorThatWillReplace) {
int width = src.getWidth();
int height = src.getHeight();
int[] pixels = new int[width * height];
// get pixel array from source
src.getPixels(pixels, 0, width, 0, 0, width, height);
Bitmap bmOut = Bitmap.createBitmap(width, height, src.getConfig());
int A, R, G, B;
int pixel;
// iteration through pixels
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
// get current index in 2D-matrix
int index = y * width + x;
pixel = pixels[index];
if(pixel == colorToReplace){
//change A-RGB individually
A = Color.alpha(colorThatWillReplace);
R = Color.red(colorThatWillReplace);
G = Color.green(colorThatWillReplace);
B = Color.blue(colorThatWillReplace);
pixels[index] = Color.argb(A,R,G,B);
/*or change the whole color
pixels[index] = colorThatWillReplace;*/
}
}
}
bmOut.setPixels(pixels, 0, width, 0, 0, width, height);
return bmOut;
}
I hope that helped :)
I have an image with frames and I need to add a watermark effect. How might I do this?
I found great tutorial on Android Image Processing here.
public static Bitmap mark(Bitmap src, String watermark, Point location, Color color, int alpha, int size, boolean underline) {
int w = src.getWidth();
int h = src.getHeight();
Bitmap result = Bitmap.createBitmap(w, h, src.getConfig());
Canvas canvas = new Canvas(result);
canvas.drawBitmap(src, 0, 0, null);
Paint paint = new Paint();
paint.setColor(color);
paint.setAlpha(alpha);
paint.setTextSize(size);
paint.setAntiAlias(true);
paint.setUnderlineText(underline);
canvas.drawText(watermark, location.x, location.y, paint);
return result;
}
Thanks to Pete Houston who shares such useful tutorial on basic image processing.
For others reference, if you want to add the logo of your application (which is in your drawable folder(s)) on top of image use following method:
private Bitmap addWaterMark(Bitmap src) {
int w = src.getWidth();
int h = src.getHeight();
Bitmap result = Bitmap.createBitmap(w, h, src.getConfig());
Canvas canvas = new Canvas(result);
canvas.drawBitmap(src, 0, 0, null);
Bitmap waterMark = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.logo);
canvas.drawBitmap(waterMark, 0, 0, null);
return result;
}
If someone is still searching for this, I found a good solution here
It adds a watermark to the bottom right portion and scales it according to the source image which was exactly what I was looking for.
/**
* Embeds an image watermark over a source image to produce
* a watermarked one.
* #param source The source image where watermark should be placed
* #param watermark Watermark image to place
* #param ratio A float value < 1 to give the ratio of watermark's height to image's height,
* try changing this from 0.20 to 0.60 to obtain right results
*/
public static Bitmap addWatermark(Bitmap source, Bitmap watermark, float ratio) {
Canvas canvas;
Paint paint;
Bitmap bmp;
Matrix matrix;
RectF r;
int width, height;
float scale;
width = source.getWidth();
height = source.getHeight();
// Create the new bitmap
bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
// Copy the original bitmap into the new one
canvas = new Canvas(bmp);
canvas.drawBitmap(source, 0, 0, paint);
// Scale the watermark to be approximately to the ratio given of the source image height
scale = (float) (((float) height * ratio) / (float) watermark.getHeight());
// Create the matrix
matrix = new Matrix();
matrix.postScale(scale, scale);
// Determine the post-scaled size of the watermark
r = new RectF(0, 0, watermark.getWidth(), watermark.getHeight());
matrix.mapRect(r);
// Move the watermark to the bottom right corner
matrix.postTranslate(width - r.width(), height - r.height());
// Draw the watermark
canvas.drawBitmap(watermark, matrix, paint);
return bmp;
}
And it is well commented which is what is a huge plus!
It seems you are looking for a waterrippleeffect as this one. Checkout the complete source code. Also check the screenshot how does the effect look like.
In Kotlin:
Note: Its just modified code of above answers
private fun mark(src: Bitmap, watermark: String): Bitmap {
val w = src.width
val h = src.height
val result = Bitmap.createBitmap(w, h, src.config)
val canvas = Canvas(result)
canvas.drawBitmap(src, 0f, 0f, null)
val paint = Paint()
paint.color = Color.RED
paint.textSize = 10f
paint.isAntiAlias = true
paint.isUnderlineText = true
canvas.drawText(watermark, 20f, 25f, paint)
return result
}
val imageBitmap = mark(yourBitmap, "Your Text")
binding.meetProofImageView.setImageBitmap(imageBitmap)
You can use androidWM to add a watermark into your image, even with invisible watermarks:
add dependence:
dependencies {
...
implementation 'com.huangyz0918:androidwm:0.2.3'
...
}
and java code:
WatermarkText watermarkText = new WatermarkText(“Hello World”)
.setPositionX(0.5)
.setPositionY(0.5)
.setTextAlpha(100)
.setTextColor(Color.WHITE)
.setTextFont(R.font.champagne)
.setTextShadow(0.1f, 5, 5, Color.BLUE);
WatermarkBuilder.create(this, backgroundBitmap)
.loadWatermarkText(watermarkText)
.getWatermark()
.setToImageView(backgroundView);
You can easily add an image type watermark or a text watermark like this, and the library size is smaller than 30Kb.
I tried a few libraries mentioned in other posts, like this, but unfortunately it is missing, and not downloadable now. So I followed AndroidLearner 's answer above, but after tweaking the code a little bit, for those of you who are having trouble rotating the watermark, and what values are valid for the various methods of Paint class, so that the text shows rotated at an angle(like most of the company watermarks do), you can use the below code.
Note that, w and h are the screen width and height respectively, which you can calculate easily, there are tons of ways you can find on stackoverflow only.
public static Bitmap waterMarkBitmap(Bitmap src, String watermark) {
int w = src.getWidth();
int h = src.getHeight();
Bitmap mutableBitmap = Utils.getMutableBitmap(src);
Bitmap result = Bitmap.createBitmap(w, h, mutableBitmap.getConfig());
Canvas canvas = new Canvas(result);
canvas.drawBitmap(src, 0f, 0f, null);
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setTextSize(92f);
paint.setAntiAlias(true);
paint.setAlpha(70); // accepts value between 0 to 255, 0 means 100% transparent, 255 means 100% opaque.
paint.setUnderlineText(false);
canvas.rotate(45, w / 10f, h / 4f);
canvas.drawText(watermark, w / 10f, h / 4f, paint);
canvas.rotate(-45, w / 10f, h / 4f);
return result;
}
It rotates the text watermark by 45 degrees, and places it at the centre of the bitmap.
Also note that, in case you are not able to get watermark, it might be the case that the bitmap you are using as source is immutable. For this worst case scenario, you can use below method to create a mutable bitmap from an immutable one.
public static Bitmap getMutableBitmap(Bitmap immutableBitmap) {
if (immutableBitmap.isMutable()) {
return immutableBitmap;
}
Bitmap workingBitmap = Bitmap.createBitmap(immutableBitmap);
return workingBitmap.copy(Bitmap.Config.ARGB_8888, true);
}
I found above method inside here. I have tested using both the methods in my application, and it works perfectly after I added above tweaks. Try it and let me know if it works or not.
use framelayout. put two imageviews inside the framelayout and specify the position of the watermark imageview.
I'm trying to create semitransparent bitmaps, I used this code:
private Bitmap SemiTransparent(Bitmap bitmap, int opacity) {
// Create an array to hold the data of bitmap for which semi transparent bitmap is to be obtained
int[] data = new int[(int)(bitmap.getWidth()) + 1];
for (int y = 0; y < bitmap.getHeight(); ++y)
{
// Get a single line of data
bitmap.getPixels(data, 0, bitmap.getWidth(), 0, y,bitmap.getWidth(), 1);
// Reset the alpha values
for (int x = bitmap.getWidth(); x>0; --x)
{
data[x] = (data[x] & 0x00ffffff) | (opacity << 24);
}
//fill alphaBitmap data
bitmap.setPixels(data, 0, bitmap.getWidth(), 0, y, bitmap.getWidth(), 1);
}
return bitmap;
}
The only problem is the background (transparent) color is always black - how can I modify this to make the background Color completely transparent and the rest still semitransparent?
Use this method to make a bitmap transparent:
/**
* #param bitmap The source bitmap.
* #param opacity a value between 0 (completely transparent) and 255 (completely
* opaque).
* #return The opacity-adjusted bitmap. If the source bitmap is mutable it will be
* adjusted and returned, otherwise a new bitmap is created.
*/
private Bitmap adjustOpacity(Bitmap bitmap, int opacity)
{
Bitmap mutableBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);
int colour = (opacity & 0xFF) << 24;
canvas.drawColor(colour, PorterDuff.Mode.DST_IN);
return mutableBitmap;
}
See an explanation here:
http://blog.uncommons.org/2011/01/12/adjusting-the-opacity-of-an-android-bitmap/
In the blog-post it checks if the bitmap is mutable or not - which can cause problems if the bitmap is mutable but doesn't have the config ARGB_8888 - so use my method instead.