Related
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;
}
We are building a native extension for air, to generate bitmap data from text.
The code below generates the bitmap of a smiley ant "test" those should bee yellow but the color is blue.
http://i.stack.imgur.com/wC1ZH.png
After a lot of searching and trying different example code we are stuck.
public static Bitmap drawText(String text, int textWidth, int textSize, String color) {
try {
text = URLDecoder.decode("%F0%9F%98%8D test", "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
// Get text dimensions
TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG);
textPaint.setColor(Color.parseColor("#ffe400"));
textPaint.setTextSize(textSize);
textPaint.setAntiAlias(true);
StaticLayout mTextLayout = new StaticLayout(text, textPaint, textWidth, Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
// Create bitmap and canvas to draw to
Bitmap b = Bitmap.createBitmap(textWidth, mTextLayout.getHeight(), Config.ARGB_8888);
Canvas c = new Canvas(b);
// Draw text
c.save();
c.translate(0, 0);
mTextLayout.draw(c);
c.restore();
Extension.log("Color " + Integer.toString(b.getPixel(15,10), 16));
return b;
}
When logging the returned pixels its already blue so we assume it goes wrong in this function.
It seems that the red and blue color channel are switched.
Fixed it by reversing the blue and red color chanel:
private static Bitmap reversColors(Bitmap b){
int width = b.getWidth();
int height = b.getHeight();
int[] pixels = new int[width * height];
b.getPixels(pixels, 0, width, 0, 0, width, height);
int[] finalArray = new int[width * height];
for(int i = 0; i < finalArray.length; i++) {
int red = Color.red(pixels[i]);
int green = Color.green(pixels[i]);
int blue = Color.blue(pixels[i]);
int alpha = Color.alpha(pixels[i]);
finalArray[i] = Color.argb(alpha, blue, green, red);
}
return Bitmap.createBitmap(finalArray, width, height, Bitmap.Config.ARGB_8888);
}
It is not the best way, but i can't find a better solution
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:
Hi everyone and beforehand thanks, I hope are well write because I am doing a simple application that should unite more than two bitmaps in only one, the problem is in which position bitmaps and size Side wrong, and the truth will not find the back for logic given to me that 's fine, in fact it is a Tengo Que code already in c # and PASE java obviously is different sin but have the same principle .
I wonder if you have the way to make the position and size of these images out as this saying in the code,
Sorry for my bad English
CODIGO JAVA
Paint mPaint;
Bitmap image1=BitmapUtils.decodeBase64(Lie.GeFondo().GetImagen());
Bitmap image2=BitmapUtils.decodeBase64(Utilidades.getImagenTomadabase64());
Bitmap image3=BitmapUtils.decodeBase64(Lie.GetBanner().GetImagen());
Bitmap result = Bitmap.createBitmap(image1.getWidth(), image1.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
Rect srcRect = new Rect(0, 0, image1.getWidth(), image1.getHeight());
Rect dstRect = new Rect(srcRect);
Rect srcRect1 = new Rect( Foto.GetPosicionDeItems().Getx(),Foto.GetPosicionDeItems().Gety(),Foto.GetTamano().GetWidth(), Foto.GetTamano().GeHeight());
Rect srcRect3 = new Rect( Lie.GetBanner().GetPosicionDeItems().Getx(), Lie.GetBanner().GetPosicionDeItems().Gety() ,Lie.GetBanner().GetTamano().GetWidth(), Lie.GetBanner().GetTamano().GeHeight());
Rect srcRect2 = new Rect(0,0,image2.getWidth(), image2.getHeight());
Rect srcRect4 = new Rect(0,0,image3.getWidth(), image3.getHeight());
dstRect.offset(0, 0);
canvas.drawBitmap(image1, srcRect, dstRect, null);
dstRect.offset(image1.getWidth(), 0);
srcRect1.offset(0, 0);
canvas.drawBitmap(image2,srcRect2 ,srcRect1 , null);
srcRect1.offset(image2.getWidth(), 0);
srcRect3.offset(0, 0);
canvas.drawBitmap(image3,srcRect4 ,srcRect3 , null);
srcRect3.offset(image3.getWidth(), 0);
myImage = (ImageView) findViewById(R.id.imageView);
myImage.setImageBitmap(result);
in Java
see java picture http://i58.tinypic.com/1zywm5u.jpg
C# Code
Ignore the foreach.
System.Drawing.Bitmap Bac = (System.Drawing.Bitmap)Lienzo.Fondo.Imagen;
System.Drawing.Graphics r = System.Drawing.Graphics.FromImage(Bac);
if (Lienzo.Fotos != null)
{
if (Lienzo.Fotos.Count > 0)
{
int i = 0;
foreach (RADMLIB.Items item in Lienzo.Fotos)
{
System.Drawing.Bitmap img = (System.Drawing.Bitmap)Lista[i];
r.DrawImage(img, item.PosicionDeItems.X, item.PosicionDeItems.Y, item.Tamano.Width, item.Tamano.Height);
i++;
}
}
}
if (Lienzo.Banner != null)
{
r.DrawImage((System.Drawing.Bitmap)Lienzo.Banner.Imagen, Lienzo.Banner.PosicionDeItems.X, Lienzo.Banner.PosicionDeItems.Y, Lienzo.Banner.Tamano.Width, Lienzo.Banner.Tamano.Height);
}
return Bac;
see c# picture http://i61.tinypic.com/s61wlh.jpg
I found the solution
using Matrix for set location and scale x,y
Bitmap image1=BitmapUtils.decodeBase64(Lie.GeFondo().GetImagen());
Bitmap image2=BitmapUtils.getResizedBitmap(BitmapUtils.decodeBase64(Utilidades.getImagenTomadabase64()),Foto.GetTamano().GetWidth(),Foto.GetTamano().GeHeight());
Bitmap image3=BitmapUtils.getResizedBitmap(BitmapUtils.decodeBase64(Lie.GetBanner().GetImagen()),Lie.GetBanner().GetTamano().GetWidth(),Lie.GetBanner().GetTamano().GeHeight());
Bitmap result = Bitmap.createBitmap(image1.getWidth(), image1.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);//Create the canvas to your image
Rect srcRect = new Rect(0, 0, image1.getWidth(), image1.getHeight());
Rect dstRect = new Rect(srcRect);
Matrix matrix = new Matrix ();
Matrix matrix2 = new Matrix ();
matrix.postTranslate( Foto.GetPosicionDeItems().Getx(),Foto.GetPosicionDeItems().Gety());
matrix2.postTranslate( Lie.GetBanner().GetPosicionDeItems().Getx(),Lie.GetBanner().GetPosicionDeItems().Gety());
canvas.drawBitmap(image1, srcRect, dstRect, null);
dstRect.offset(image1.getWidth(), 0);
canvas.drawBitmap(image2,matrix , null);
canvas.drawBitmap(image3,matrix2 , null);
getResizedBitmap Method
public static Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
return resizedBitmap;
}
see the image
https://lh4.ggpht.com/LXW8kVc3U8qQUHnORI-3H4H-A2hjq92y_oEDsKIs-iBDkVBFTgjGP03xFReCeuyLlg=h900-rw
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);
}
}