I am trying to add a simple 2d Image (.png format) to my 2d Game. My game consists of a Game View Class that extends surface view, a GameState Class, that Controls the logic of the game, and draws the canvas and a Main Activity. My GameState class has this method:
// the draw method
public void draw(Canvas canvas, Paint paint) {
// Clear the screen
canvas.drawRGB(20, 20, 20);
// set the colour
paint.setARGB(200, 0, 200, 0);
// // draw the bats
// canvas.drawRect(new Rect(_bottomBatX, _bottomBatY, _bottomBatX
// + _batLength, _bottomBatY + _batHeight), paint); // bottom bat
}
It is responsible for drawing all the objects on the game. I can easily draw a rectangle. But i cannot figure out how to draw an Image into my game. I plan on having the image move dynamically (like a sprite).
How can i draw a sprite inside of the above method?
I cannot do it this way:
bmp = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
since GameState does not extend View
Thank you
A simple solution would be.
first you need to store your image in the asset folder
then you need to call the AssetManager to get the assets in your assets folder
Bitmap yourImage;
AssetManager assetManager = context.getAssets();
get the byte stream of your image
InputStream inputStream;
inputStream = assetManager.open("yourImage.png");
// path is relative to the assets folder
let the BitmapFactory do its work in decoding it and storing it to the yourImage variable of type Bitmap
yourImage = BitmapFactory.decodeStream(inputStream);
inputStream.close();
then you need to call a method in the canvas object
canvas.drawBitmap(bitmap, x, y, paint);
The parameters of the method are:
bitmap The bitmap to be drawn
x The position of the left side of the bitmap being drawn
y The position of the top side of the bitmap being drawn
paint The paint used to draw the bitmap (usualy this is null)
Example:
canvas.drawBitmap(yourImage, 100, 100, null);
Related
I want to develop an application that takes a photograph and allows you to select a frame for photography.
I already have developed the interfaces, like taking the photo and storing it.
But I put a frame to the photo taken I could not.
Any recommendation?
In what format do you store taken photos and your frame images? If you plan to insert your picture into a simple frame, I'd suggest to first draw your taken picture on a Canvas, and then draw your frame over it. Keep in mind the sizing - you don't want your picture be too small or too big.
I'm providing an example snippet here:
public Bitmap Output(Bitmap takenPhoto, Bitmap frameImage)
{
int width, height, x, y;
height = ### // your desired height of the whole output image
width = ### // your desired width of the whole output image
x = ### // specify indentation for the picture
y = ###
Bitmap result = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(result);
Paint paint = new Paint();
c.drawBitmap(takenPhoto, x, y, paint); // draw your photo over canvas, keep indentation in mind (x and y)
c.drawBitmap(frameImage, 0, 0, paint); // now draw your frame on top of the image
return result;
}
Keep in mind that I have not tested the code and you might (actually, you'll have to) apply corrections.
Thanks for the help, I put my solution :
ImageView Resultado;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Bitmap miBitmap = Bitmap.createBitmap(1000, 1000, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(miBitmap);
Paint paint = new Paint();
c.drawBitmap(drawableToBitmap(R.mipmap.ic_launcher), 500, 500, paint); // draw your photo over canvas, keep indentation in mind (x and y)
c.drawBitmap(drawableToBitmap(R.drawable.silver_frame), 0, 0, paint); // now draw your frame on top of the image
Resultado.setImageBitmap(miBitmap);
}
public Bitmap drawableToBitmap(int imagen){
return BitmapFactory.decodeResource(getApplicationContext().getResources(), imagen);
}
I want to draw a drawable on canvas with this code but it doesn't work and i don't know why
getResources().getDrawable(R.drawable.allergist).draw(canvas);
I set my custom views heigh and width to match parent but whole screen is white and there is no drawable on screen
You need to load your image as bitmap:
Resources res = getResources();
Bitmap bitmap = BitmapFactory.decodeResource(res, R.drawable.allergist);
Then make the bitmap mutable and create a canvas over it:
Canvas canvas = new Canvas(bitmap.copy(Bitmap.Config.ARGB_8888, true));
After that you can draw it on canvas.
EDIT 1
Set bounds To Drawable.
Drawable d = getResources().getDrawable(R.drawable.allergist);
d.setBounds(left, top, right, bottom);
d.draw(canvas);
We had a similar problem, and we solved it by calling drawable.invalidateSelf(). After that, it rendered successfully onto our Canvas.
I have the following code which I got from a youtube tutorial for drawing canvas:
(https://www.youtube.com/watch?v=6NBt36fO0iw):
#Override
protected void onDraw(Canvas canvasporch) {
canvasporch.drawColor(Color.BLACK);
for (int i = temps.size() - 1; i >= 0; i--){
temps.get(i).onDraw(canvasporch);
for (Sprite sprite : sprites){
sprite.onDraw(canvasporch);
This works just fine. The only problem is instead of having the color Black as background, I want to display an image from my drawable folder as the background for my sprites. I've tried using drawBitmap() but I cannot seem to make it work. Thanks.
1) Create a member variable to store the Bitmap:
Bitmap spriteBackground;
2) In onCreate() (or some other initialization function) load the bitmap from the drawable:
spriteBackground = BitmapFactory.decodeResource(getResources(), R.drawable.sprite_background);
3) Draw the bitmap using drawBitmap() inside onDraw():
canvasporch.drawBitmap(spriteBackground, 0, 0, null);
If you want to scale the bitmap to cover the canvas then either scale it at load time using createScaledBitmap (uses more memory) or apply a matrix transform to the canvas (possibly slower).
Another way is to pass the canvas bounds to drawBitmap(), like this:
canvasporch.drawBitmap(spriteBackground, null, canvasporch.getClipBounds(), null);
I'm struggling to draw a rotating bitmap around its center and do the rotating without resizing the bitmap. I'm drawing all my sprites to the screen via a game thread, so I'm looking for a solution that incorporates the original bitmap and not the canvas.
Thanks in advance.
This is my code so far, it turns a bitmap around its center, yet resizes it.
i = i + 2;
transform.postRotate(i, Assets.scoresScreen_LevelStar.getWidth()/2, Assets.scoresScreen_LevelStar.getHeight()/2);
Bitmap resizedBitmap = Bitmap.createBitmap(Assets.scoresScreen_LevelStar, 0, 0, Assets.scoresScreen_LevelStar.getWidth(), Assets.scoresScreen_LevelStar.getHeight(), transform, true);
game.getGraphics().getCanvasGameScreen().drawBitmap(resizedBitmap, null, this.levelStar.getHolderPolygons().get(0), null);
Update:
I've noticed this isn't as easy as it sounds. My rotating code is not the problem. The bitmap rotates, yet the dst rect will also have to increase/decrease depending on the angle of rotation, or else the bimap will appear smaller, since it's drawn into a fixed dst rect.
So I'm guessing I'll have to develop some method that will return a dst rect.
So the methods needed to rotate a bitmap without appeared resizing:
public static Bitmap rotateBitmap(Bitmap bitmap, int rotation) // I've got this method working
and
public static Rect rotateRect(Rect currentDst, int rotation) // Don't got this
I understand this will require some math (trig), anyone up for the challenge? :P
You should draw the bitmap using the Matrix class. Below is a very basic idea assuming that you want to rotate an image inside of a "Ship" class. You update the current position Matrix inside the update method. In the onDraw() you draw the bitmap using the newly updated position Matrix. This will draw the rotated bitmap without resizing it.
public class Ship extends View {
private float x, y;
private int rotation;
private Matrix position;
private Bitmap bitmap;
...
#Override
public void onDraw(Canvas canvas) {
// Draw the Bitmap using the current position
canvas.drawBitmap(bitmap, position, null);
}
public void update() {
// Generate a new matrix based off of the current rotation and x and y coordinates.
Matrix m = new Matrix();
m.postRotate(rotation, bitmap.getWidth()/2, bitmap.getHeight()/2);
m.postTranslate(x, y);
// Set the current position to the updated rotation
position.set(m);
rotation += 2;
}
....
}
Hope that helps!
Also keep in mind that generating a new Bitmap object inside you game loop will be resource intensive.
This worked for me!
I created a method that returns a matrix. The matrix can be used in the following drawing method:
public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint)
Here you go! (The parameter shape can be replaced with ease, if you would like that, just leave a comment):
public static Matrix rotateMatrix(Bitmap bitmap, Shape shape, int rotation) {
float scaleWidth = ((float) shape.getWidth()) / bitmap.getWidth();
float scaleHeight = ((float) shape.getHeight()) / bitmap.getHeight();
Matrix rotateMatrix = new Matrix();
rotateMatrix.postScale(scaleWidth, scaleHeight);
rotateMatrix.postRotate(rotation, shape.getWidth()/2, shape.getHeight()/2);
rotateMatrix.postTranslate(shape.getX(), shape.getY());
return rotateMatrix;
}
NB: If you want an animated rotation, the rotation parameter will have to be updated with new values every frame eg. 1 then 2 then 3 ...
is there a way to arrange drawable drawen on canvas, before redrawing it? I mean setting which drawable will be drawn in the front, and which drawable will be drawn in the back.
They're drawn in the order you draw them. Just try drawing the one which sits in the back first, the front one last.
A way to do it is to have everything you draw define a z-index variable and collect everything you draw at a single point and put them in a list that you then order by the z-index before drawing it.
ex:
Interface IDrawable{
int getZ();
void draw();
}
class drawMe implements IDrawable{
#overrider
draw(){
/// do my drawing
}
#override
int getZ() {return z; }
}
in your drawing or main class
List<IDrawable> myList= new ArrayList();
myList.Add(new DrawMe());
and in your draw method
for(IDrawable draw : myList.OrderBy(z){
draw.draw();
}
thats the concept anyway
You can draw to a temporary canvas for drawing to the main canvas later.
Picture iconFrame = new Picture();
Canvas tempCanvas = iconFrame.beginRecording(width, height);
// width and height refer to the intended destination canvas size
...
// Any configuration before performing the draw should be done here
tempCanvas.drawPath(...);
tempCanvas.drawBitmap(...);
// Any required draw commands for this image should be done to tempCanvas
iconFrame.endRecording();
...
// Any other configuration or draw commands can be done here
iconFrame.draw(canvas);
// Assigns the content of tempCanvas to the top of the main Canvas
In my case, the PorterDuff manipulation of my image within a custom path only worked if it was done first because later draws corrupted it.