Convert filtered drawable to bitmap - java

I've got a drawable I'm applying a filter to using
drawable.setColorFilter (color, PorterDuff.MILTIPLY)
Then I'm taking the bitmap I used to create the drawable and putting it into a canvas so I can write text in the middle of the png. And finishing by writing
drawable.draw(canvas)
I want the text I add to always be white no matter what color filter is used but right now the text becomes whatever color is used for filtering. I was thinking if I could convert the filtered drawable to a bitmap then add the text the it'd work but so far it hasnt. Any help or suggestions would be greatly appreciated.
Here is my code
public void setDrawableFilter(String text, int color) {
mBitmap = scaleBitmap(250, 238);
mDrawable = new BitmapDrawable(mContext.getResources(), mBitmap);
mDrawable.setColorFilter(color, PorterDuff.Mode.MULTIPLY);
addTextToBitmap(text);
}
public void addTextToBitmap(String text){
Canvas canvas = new Canvas(mBitmap);
mDrawable.draw(canvas);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setTextSize(35);
paint.setColor(Color.WHITE);
int canvasWidth = canvas.getWidth();
int canvasHeight = canvas.getHeight();
float xPercent = 0.38f;
float yPercent = 0.58f;
int textX = (int) (canvasWidth * xPercent);//
int textY = (int) (canvasHeight * yPercent);
paint.setTextAlign(Paint.Align.CENTER);
canvas.drawText(text, canvasWidth / 2, textY, paint);
}

Related

Java barcode generator [duplicate]

I want to add a string on bitmap image.I have a metod drawTextToBitmap,this method working success place string on bitmap image.But my bitmap image is very small like pinmark image.This function set the string based on the bitmap height and width.I want to place the string exceed than the bitmap image.So Please help me to solve the problem.
Following method i am using to get bitmap :
public Bitmap drawTextToBitmap(Context gContext, int gResId, String gText) {
Resources resources = gContext.getResources();
float scale = resources.getDisplayMetrics().density;
Bitmap bitmap = BitmapFactory.decodeResource(resources, gResId);
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
// set default bitmap config if none
if (bitmapConfig == null) {
bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
}
// resource bitmaps are imutable,
// so we need to convert it to mutable one
bitmap = bitmap.copy(bitmapConfig, true);
Canvas canvas = new Canvas(bitmap);
// new antialised Paint
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
// text color - #3D3D3D
paint.setColor(Color.BLACK);
// text size in pixels
paint.setTextSize((int) (70 * scale));
// text shadow
paint.setShadowLayer(1f, 0f, 1f, Color.BLACK);
// draw text to the Canvas center
Rect bounds = new Rect();
paint.getTextBounds(gText, 0, gText.length(), bounds);
int m = (bitmap.getWidth() - bounds.width()) / 2;
int l = (bitmap.getHeight() + bounds.height()) / 2;
canvas.drawText(gText, 1000, l, paint);
return bitmap;
}
Try this:
public static Bitmap drawStringonBitmap(Bitmap src, String string, Point location, int color, int alpha, int size, boolean underline,int width ,int height) {
Bitmap result = Bitmap.createBitmap(width, height, 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(string, location.x, location.y, paint);
return result;
}

Scaling down and making image square in android

I need a way to scale an image down to 78x78. I have found ways of doing this by cutting part of the image off, like this:
Bitmap image = Bitmap.createBitmap(image, 0, 0, 78, 78);
but I need to maintain as much of the image as possible. I had thought of scaling the image down and then making it square:
Bitmap image = Bitmap.createScaledBitmap(imageTest, 78, 78, true);
but of course this creates a square image that is squashed.
Can anyone suggest how I can create a 78x78 image that doesn't rescale and maintains as much of the original image as possible?
From what I understood, you should scale down and center crop the image. Try this code out.
public Bitmap scaleCenterCrop(Bitmap source, int newHeight, int newWidth) {
int sourceWidth = source.getWidth();
int sourceHeight = source.getHeight();
// Compute the scaling factors to fit the new height and width, respectively.
// To cover the final image, the final scaling will be the bigger
// of these two.
float xScale = (float) newWidth / sourceWidth;
float yScale = (float) newHeight / sourceHeight;
float scale = Math.max(xScale, yScale);
// Now get the size of the source bitmap when scaled
float scaledWidth = scale * sourceWidth;
float scaledHeight = scale * sourceHeight;
// Let's find out the upper left coordinates if the scaled bitmap
// should be centered in the new size give by the parameters
float left = (newWidth - scaledWidth) / 2;
float top = (newHeight - scaledHeight) / 2;
// The target rectangle for the new, scaled version of the source bitmap will now
// be
RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight);
// Finally, we create a new bitmap of the specified size and draw our new,
// scaled bitmap onto it.
Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig());
Canvas canvas = new Canvas(dest);
canvas.drawBitmap(source, null, targetRect, null);
return dest;
}
Hope it helps
Try this:
Bitmap image = Bitmap.createScaledBitmap(testImage, (int) 78 * (testImage.getWidth() / testImage.getHeight()), 78, true);
image = Bitmap.createBitmap(image, (int) (image.getWidth() - 78) / 2, 78);
Haven't tested this, as I'm on my way to bed, but it should accomplish what you want, so long as your image has a width greater than or equal to its height.
Regardless, I'd suggest you use BufferedImage instead of Bitmap.
The idea here would be resize your image using the same resize rate for width and height keeping the smaller size in 78. After that you can use a center point based crop to get the middle of your image and making it a squared image.
Image srcImage;
int widthSrc = 150;
int heightSrc = 180;
float resizeRate = 78 / min(widthSrc, heightSrc);
Image resizedImage = resizeImage($srcImage, resizeRate);
int widthDest = 78;
int heightDest = 78;
int cropX = ($widthSrc - $widthDest)/2;
int cropY = ($heightSrc - $heightDest)/2;
Image croppedImage = cropImage(resizedImage,$widthDest, $heightDest, $cropX, $cropY);
If the image is already square you can skip the crop part.

Create 3D cube with Canvas

I have a 2d bitmap that I would like to convert into a 3d cube(example like in minecraft: )
I managed to rotate around images in 3d space using the "Camera" but I can't understand how to control it or how to create a cube out of it, anyone has ideas? Please notice i'm allowed only to use canvas and no OpenGL.
Edit:
this is as close as I got:
using this code:
Matrix mMatrix = canvas.getMatrix();
canvas.save();
Camera camera=new Camera();
camera.save();
camera.rotateY(30);
camera.getMatrix(mMatrix);
mMatrix.preTranslate(-30, 0);
mMatrix.postTranslate(30, 0);
canvas.concat(mMatrix);
canvas.drawBitmap(b, 150, 150, null);
canvas.drawBitmap(b, 180, 180, null);
camera.restore();
canvas.restore();
canvas.save();
Okay, so because none helped me I looked for another way of doing it and thought of a workaround way that works, its not efficient and it might slow the program down while doing it, so think twice before using it.
The way I did it is like that:
First of all, I created a cube in paint (could be any 3D shape)
Then, I cut the cube sides and saved them separately.
After loading those images all is left is the code:
public Bitmap CreateACube(Bitmap b2D){
Bitmap result=Bitmap.createBitmap(b2D);
/*loading sides of cube and painting texture on them*/
Bitmap top;
Bitmap left;
Bitmap front;
top=BitmapFactory.decodeResource(getResources(), R.drawable.top);
top=CubeCreator(top, b2D,"top");
left=BitmapFactory.decodeResource(getResources(), R.drawable.left);
left=CubeCreator(left, b2D,"left");
front=BitmapFactory.decodeResource(getResources(), R.drawable.front);
front=CubeCreator(front, b2D,"front");
Bitmap merge;
merge=overlay(top, left);//connecting all cube sides together into one bitmap
merge=overlay(merge, front);
result=Bitmap.createScaledBitmap(merge, merge.getWidth()*2, merge.getHeight()*2, false); //Scaling the result, you can remove if you don't want to.
return result;
}
private Bitmap CubeCreator(Bitmap srcBmp,Bitmap b2D,String s){
/*gets cube side bitmap, the texture bitmap, and a string of the side name*/
int width = srcBmp.getWidth();
int height = srcBmp.getHeight();
int width2=b2D.getWidth();
int height2=b2D.getHeight();
int rows1=0;
int rows2=0;
Bitmap dstBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
/*Running on every pixel in the cube side*/
for (int row = 0; row < height; row++) {
rows1=++rows1%height2; //running on every pixel on the texture and reseting it if reached the last pixel
for (int col = 0; col < width; col++) {
rows2=++rows2%width2;
int pixel = srcBmp.getPixel(col, row);
int alpha = Color.alpha(pixel);
int dstColor=b2D.getPixel(rows2, rows1);
switch(s){//you can add more sides, I used 3
case "front":{
float[] hsv = new float[3];
int color = dstColor;
Color.colorToHSV(color, hsv);
hsv[2] *= 0.8f; // giving brightness to certain sides to make it look more 3D
dstColor = Color.HSVToColor(hsv);
break;
}
case "left":{
float[] hsv = new float[3];
int color = dstColor;
Color.colorToHSV(color, hsv);
hsv[2] *= 0.44f;
dstColor = Color.HSVToColor(hsv);
break;
}
case "top":{
float[] hsv = new float[3];
int color = dstColor;
Color.colorToHSV(color, hsv);
hsv[2] *= 1.2f;
dstColor = Color.HSVToColor(hsv);
break;
}
}
int pixel2=srcBmp.getPixel(col, row);
if(pixel2!= Color.TRANSPARENT)//checking if the current pixel of the side is not transparent
dstBitmap.setPixel(col, row, dstColor);
else{
dstBitmap.setPixel(col, row, pixel2);
}
}
}
return dstBitmap;
}
public static Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {
/*connects two bitmaps together*/
Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp1, new Matrix(), null);
canvas.drawBitmap(bmp2, 0, 0, null);
return bmOverlay;
}
Summary of the code: I run on every pixel of the cube side (front, left, top) and while doing so I also run on every pixel in the texture bitmap, and color the side pixels with the pixels of the texture. After it I connect all colored sides together into one bitmap and return them.
Result:

Rotate a saved bitmap in android

I am saving an image from the camera that was in landscape mode. so it gets saved in landscape mode and then i apply an overlay onto it that too is in landscape mode. I want to rotate that image and then save. e.g. if i have this
I want to rotate clockwise by 90 degrees once and make it this and save it to sdcard:
How is this to be accomplished?
void rotate(float x)
{
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(),R.drawable.tedd);
int width = bitmapOrg.getWidth();
int height = bitmapOrg.getHeight();
int newWidth = 200;
int newHeight = 200;
// calculate the scale - in this case = 0.4f
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
matrix.postRotate(x);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmapOrg, 0, 0,width, height, matrix, true);
iv.setScaleType(ScaleType.CENTER);
iv.setImageBitmap(resizedBitmap);
}
Check this
public static Bitmap rotateImage(Bitmap src, float degree)
{
// create new matrix
Matrix matrix = new Matrix();
// setup rotation degree
matrix.postRotate(degree);
Bitmap bmp = Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true);
return bmp;
}
You can use the Canvas API to do that. Note that you need to switch width and height.
final int width = landscapeBitmap.getWidth();
final int height = landscapeBitmap.getHeight();
Bitmap portraitBitmap = Bitmap.createBitmap(height, width, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(portraitBitmap);
c.rotate(90, height/2, width/2);
c.drawBitmap(landscapeBitmap, 0,0,null);
portraitBitmap.compress(CompressFormat.JPEG, 100, stream);
Use a Matrix.rotate(degrees) and draw the Bitmap to it's own Canvas using that rotating matrix. I don't know though if you might have to make a copy of the bitmap before drawing.
Use Bitmap.compress(...) to compress your bitmap to an outputstream.
The solution of Singhak works fine.
In case you need fit the size of result bitmap (perhaps for ImageView) you can expand the method as follows:
public static Bitmap rotateBitmapZoom(Bitmap bmOrg, float degree, float zoom){
Matrix matrix = new Matrix();
matrix.postRotate(degree);
float newHeight = bmOrg.getHeight() * zoom;
float newWidth = bmOrg.getWidth() / 100 * (100.0f / bmOrg.getHeight() * newHeight);
return Bitmap.createBitmap(bmOrg, 0, 0, (int)newWidth, (int)newHeight, matrix, true);
}

How to change a bitmap's opacity?

I have a bitmap:
Bitmap bitmap = BitmapFactory.decodeFile("some/arbitrary/path/image.jpg");
But I'm not going to display the image to the user. I want the alpha to be 100 (out of 255). If this is not possible, can I set the opacity of the Bitmap?
As far as I know, opacity or other color filters can't be set on the Bitmap itself. You will need to set the alpha when you use the image:
If you're using ImageView, there is ImageView.setAlpha().
If you're using a Canvas, then you need to use Paint.setAlpha():
Paint paint = new Paint();
paint.setAlpha(100);
canvas.drawBitmap(bitmap, src, dst, paint);
Also, incorporating WarrenFaith's answer, if you will use the Bitmap where a drawable is required, you can use BitmapDrawable.setAlpha().
You could also try BitmapDrawable instead of Bitmap. If this is useful for you depends on the way you use the bitmap...
Edit
As a commenter asked how he can store the bitmap with alpha, here is some code:
// lets create a new empty bitmap
Bitmap newBitmap = Bitmap.createBitmap(originalBitmap.getWidth(), originalBitmap.getHeight(), Bitmap.Config.ARGB_8888);
// create a canvas where we can draw on
Canvas canvas = new Canvas(newBitmap);
// create a paint instance with alpha
Paint alphaPaint = new Paint();
alphaPaint.setAlpha(42);
// now lets draw using alphaPaint instance
canvas.drawBitmap(originalBitmap, 0, 0, alphaPaint);
// now lets store the bitmap to a file - the canvas has drawn on the newBitmap, so we can just store that one
// please add stream handling with try/catch blocks
FileOutputStream fos = new FileOutputStream(new File("/awesome/path/to/bitmap.png"));
newBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
public Bitmap makeTransparent(Bitmap src, int value) {
int width = src.getWidth();
int height = src.getHeight();
Bitmap transBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
Canvas canvas = new Canvas(transBitmap);
canvas.drawARGB(0, 0, 0, 0);
// config paint
final Paint paint = new Paint();
paint.setAlpha(value);
canvas.drawBitmap(src, 0, 0, paint);
return transBitmap;
}
Bitmap bgr = BitmapFactory.decodeResource(getResources(),R.drawable.main_logo_2);
Paint transparentpainthack = new Paint();
transparentpainthack.setAlpha(100);
canvas.drawBitmap(bgr, 0, 0, transparentpainthack);
https://dzone.com/articles/adjusting-opacity-android proposes:
/**
* #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.isMutable()
? bitmap
: 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;
}
Note that with DST_IN you can modify (rather than reset) the transparency of already transparent image, that is, you can make the image more and more transparent.
If you are using a Drawable to display the image, you can change the alpha as follows:
private Drawable mTriangle;
mTriangle = context.getResources().getDrawable(R.drawable.triangle_arrow_for_radar);
...
protected void onDraw(Canvas canvas)
{
// Draw the triangle arrow
float imageTargetWidth = getWidth() / 15;
float scale = mTriangle.getIntrinsicWidth() / imageTargetWidth;
int imgWidth = (int)(imageTargetWidth);
int imgHeight = (int)(mTriangle.getIntrinsicHeight() / scale);
if (mTriangle != null)
{
mTriangle.setBounds(getWidth() / 2 - imgWidth / 2, getHeight() / 2 - imgHeight / 2, getWidth() / 2 + imgWidth / 2, getHeight() / 2 + imgHeight / 2);
mTriangle.setAlpha(150); // from (transparent) to 255 (opaque)
mTriangle.draw(canvas);
}
}

Categories