Android drawing multiple different size bitmaps to same size canvas - java

I have some different size bitmap here:
and I want to resize them to same width and height (64px) each image
here is what I did:
int size = Math.round(64 * getResources().getDisplayMetrics().density);
int imagesLength = 4;
Bitmap bmp = Bitmap.createBitmap(size*imagesLength, size, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
for (int i = 0; i < imagesLength; i++) {
Bitmap mImage = getImage(i);
// ...code to get bitmap...
canvas.drawBitmap(mImage,i * size, 0, null);
}
do anyone got an idea? thanks

You can use Bitmap.createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter) to change the image to the size you want.
But this will not keep the aspect ratio intact. If thats important you might want to think of something else. Like scaling it down as you already did and adding it centered on some kind of background.
This gets you square bitmaps, no matter what:
int size = Math.round(64 * getResources().getDisplayMetrics().density);
int imagesLength = 4;
Bitmap bmp = Bitmap.createBitmap(size*imagesLength, size, Bitmap.Config.ARGB_8888); // the bitmap you paint to
Canvas canvas = new Canvas(bmp);
for (int i = 0; i < imagesLength; i++) {
Bitmap mImage = getImage(i);
// ...code to get bitmap...
mImage = Bitmap.createScaledBitmap(mImage , size, size, true);
canvas.drawBitmap(mImage,i * size, 0, null);
}
And this is for keeping the ratio but leaving gaps:
int size = Math.round(64 * getResources().getDisplayMetrics().density);
int imagesLength = 4;
Bitmap bmp = Bitmap.createBitmap(size*imagesLength, size, Bitmap.Config.ARGB_8888); // the bitmap you paint to
Canvas canvas = new Canvas(bmp);
for (int i = 0; i < imagesLength; i++) {
Bitmap mImage = getImage(i);
// ...code to get bitmap...
int width = mImage.getWidth();
int height= mImage.getHeight();
float ratio = width/(float)height;
if(ratio>1)
{
mImage = Bitmap.createScaledBitmap(mImage , size, size/ratio, true);
}
else
{
mImage = Bitmap.createScaledBitmap(mImage , size*ratio, size, true);
}
canvas.drawBitmap(mImage,i * size, 0, null);
}

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;
}

How to rotate bitmap in android?

My bitmap is rotated but is overlaped with original image.
Bitmap source
public void onImageAvailable(ImageReader reader) {
final Image image = reader.acquireNextImage();
// final Image image = reader.acquireLatestImage();
final ByteBuffer yuvBytes = imageToByteBuffer(image);
// Convert YUV to RGB
final RenderScript rs = RenderScript.create(MainActivity.this);
Bitmap bitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
final Allocation allocationRgb = Allocation.createFromBitmap(rs, bitmap);
final Allocation allocationYuv = Allocation.createSized(rs, Element.U8(rs), yuvBytes.array().length);
allocationYuv.copyFrom(yuvBytes.array());
ScriptIntrinsicYuvToRGB scriptYuvToRgb = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
scriptYuvToRgb.setInput(allocationYuv);
scriptYuvToRgb.forEach(allocationRgb);
allocationRgb.copyTo(bitmap);
int rotation = MainActivity.this.getWindowManager().getDefaultDisplay().getRotation();
int x = bitmap.getWidth();
int y = bitmap.getHeight();
Bitmap bitmap1 = Bitmap.createScaledBitmap(bitmap, y, x, true);
Bitmap rotatedBitmap = rotateBitmap(bitmap1, getOrientation(rotation));
RotatedBitmapFunction
public Bitmap rotateBitmap(Bitmap original, float degrees) {
int width = original.getWidth();
int height = original.getHeight();
Matrix matrix = new Matrix();
matrix.preRotate(degrees);
Bitmap rotatedBitmap = Bitmap.createBitmap(original, 0, 0, width, height, matrix, true);
Canvas canvas = new Canvas(rotatedBitmap);
canvas.drawBitmap(original, 5.0f, 0.0f, null);
return rotatedBitmap;
}
Output
The original bitmap is stacked on top of rotatedbitmap.
#Problem
Check these lines in your code
Canvas canvas = new Canvas(rotatedBitmap);
canvas.drawBitmap(original, 5.0f, 0.0f, null);
Why you are drawing the origin bitmap in the canvas just before returning the rotated Bitmap.
I guess this is the issue.
Solved It
public Bitmap rotateBitmap(Bitmap original, float degrees) {
int x = original.getWidth();
int y = original.getHeight();
Matrix matrix = new Matrix();
matrix.preRotate(degrees);
Bitmap rotatedBitmap = Bitmap.createBitmap(original , 0, 0, original .getWidth(), original .getHeight(), matrix, true);
return rotatedBitmap;
}

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:

canvas.drawBitmap bad Location and size (not placing image correctly)

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

Drawing on a transparent image using Java SWT

How do I create an in-memory fully transparent SWT image and draw a black line on it with antialias enabled?
I expect the result to include only black color and alpha values ranging from 0 to 255 due to antialias...
I googled and tried everything that I could... is this possible at all?
This is how I did and it works:
Image src = new Image(null, 16, 16);
ImageData imageData = src.getImageData();
imageData.transparentPixel = imageData.getPixel(0, 0);
src.dispose();
Image icon = new Image(null, imageData);
//draw on the icon with gc
I was able to make this work, although it feels a bit hacky:
Display display = Display.getDefault();
int width = 10;
int height = 10;
Image canvas = new Image(display, width, height);
GC gc = new GC(canvas);
gc.setAntialias(SWT.ON);
// This sets the alpha on the entire canvas to transparent
gc.setAlpha(0);
gc.fillRectangle(0, 0, width, height);
// Reset our alpha and draw a line
gc.setAlpha(255);
gc.setForeground(display.getSystemColor(SWT.COLOR_BLACK));
gc.drawLine(0, 0, width, height);
// We're done with the GC, so dispose of it
gc.dispose();
ImageData canvasData = canvas.getImageData();
canvasData.alphaData = new byte[width * height];
// This is the hacky bit that is making assumptions about
// the underlying ImageData. In my case it is 32 bit data
// so every 4th byte in the data array is the alpha for that
// pixel...
for (int idx = 0; idx < (width * height); idx++) {
int coord = (idx * 4) + 3;
canvasData.alphaData[idx] = canvasData.data[coord];
}
// Now that we've set the alphaData, we can create our
// final image
Image finalImage = new Image(canvasData);
// And get rid of the canvas
canvas.dispose();
After this, finalImage can be drawn into a GC with drawImage and the transparent parts will be respected.
I made it by allocating an ImageData, making it transparent then creating the Image from the data :
static Image createTransparentImage(Display display, int width, int height) {
// allocate an image data
ImageData imData = new ImageData(width, height, 24, new PaletteData(0xff0000,0x00ff00, 0x0000ff));
imData.setAlpha(0, 0, 0); // just to force alpha array allocation with the right size
Arrays.fill(imData.alphaData, (byte) 0); // set whole image as transparent
// Initialize image from transparent image data
return new Image(display, imData);
}
To scale with transparency, I've found that I have to manually set the alpha byte array as shown below. So the alpha ends up with nearest-neighbor anti aliasing.
public static Image scaleImage(Device device, Image orig, int scaledWidth, int scaledHeight) {
Rectangle origBounds = orig.getBounds();
if (origBounds.width == scaledWidth && origBounds.height == scaledHeight) {
return orig;
}
ImageData origData = orig.getImageData();
ImageData imData = new ImageData(scaledWidth, scaledHeight, origData.depth, origData.palette);
if (origData.alphaData != null) {
imData.alphaData = new byte[imData.width * imData.height];
for (int row = 0; row < imData.height; row++) {
for (int col = 0; col < imData.width; col++) {
int origRow = row * origData.height / imData.height;
int origCol = col * origData.width / imData.width;
byte origAlpha = origData.alphaData[origRow * origData.width + origCol];
imData.alphaData[row * imData.width + col] = origAlpha;
}
}
}
final Image scaled = new Image(device, imData);
GC gc = new GC(scaled);
gc.setAntialias(SWT.ON);
gc.setInterpolation(SWT.HIGH);
gc.setBackground(device.getSystemColor(SWT.COLOR_WHITE));
gc.fillRectangle(0, 0, scaledWidth, scaledHeight);
gc.drawImage(orig, 0, 0, origBounds.width, origBounds.height, 0, 0, scaledWidth, scaledHeight);
gc.dispose();
return scaled;
}

Categories