onOffsetsChanged: move Bitmap - java

i want my Bitmap that has the height of the screen and has a bigger width than the screen to be moved a little bit to the right or left if the user changes the desktop so he can see the entire image.
Here is my code that just works partially:
int x = -1*(int)((xOffset*bmp.getWidth()));
canvas.drawBitmap(bmp, x, 0, null);
thank you!

You get exact pixel values via the variables xPixels and yPixels in onOffsetsChanged(). See my answer here: android live wallpaper rescaling
For example, in onOffsetsChanged(), you can set a private class variable
mPixels = xPixels;
Then, in your draw routine
holder = getSurfaceHolder();
c = holder.lockCanvas();
c.translate(mPixels, 0f);
// c.drawBitmap ... goes here :-)
Typically, you will want a bitmap twice the width of your screen, with your artwork centered in the middle. For example: 320 pixel width screen -> 640 pixel width bitmap with "center" from 160 to 480. mPixels will be 0 at the left most launcher screen (of 5), -160 at the center, and -320 at the rightmost screen.

Related

libGDX Draw viewport only partly while cutting off the rest

This problem seemed very obvious for me to solve, but whatever I try, it doesn't work. What I'm trying to do is to incorporate a mini-version of my PlayScreen in a ScrollPane as a tutorial where you can read text and try it out immediately.
Because I didn't find any better solution to add this to the Table inside the ScrollPane, I edited the draw() method of the PlayScreen to take the ScrollPane.getScrollPercentY() and offset the camera of the PlayScreen accordingly.
What I want to do now is to only render only part of the viewport that would be normally visible in the real game. Subsequently, I want to be able to control the size and position of this "window".
I also want to be able to resize and move the content, while cutting off the edges that are not visible to the camera. This is what I tried inside the PlayScreenDraw:
public void draw(final float yOffset,
final int xTiles,
final int yTiles) {
view.getCamera().position.y = yTiles / 2f - yOffset * yTiles / HEIGHT; // HEIGHT = 800
view.getCamera().position.x = xTiles / 2f;
view.setWorldSize(xTiles, yTiles); //Do i even need to change the world size?
b.setProjectionMatrix(view.getCamera().combined);
b.begin();
...
b.end();
view.update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
}
What this gives me, in terms of the picture above, is this
How do I need to change the viewport and/or the camera? Btw., this is how i set the two up:
cam = new OrthographicCamera();
cam.setToOrtho(false, WIDTH, HEIGHT); // WIDTH = 8, HEIGHT = 16
batch.setProjectionMatrix(cam.combined);
view = new FitViewport(WIDTH, HEIGHT, cam);
The Pixmap class can help you achieve what you want since you stated that you wanted to "cut off" the parts outside of the green selection box.
You need to render what the camera sees to an FBO and then get the pixmap from the FBO itself.
Framebuffer Objects are OpenGL Objects, which allow for the creation of user-defined Framebuffers. With them, one can render to non-Default Framebuffer locations, and thus render without disturbing the main screen.
-- OpenGL wiki
// Construct an FBO and keep a reference to it. Remember to dispose of it.
FrameBuffer fbo = new FrameBuffer(Format.RGBA8888, width, height, false);
public void render() {
//Start rendering to the fbo.
fbo.begin();
//From the camera's perspective.
batch.setProjectionMatrix(camera.combined);
batch.begin();
//Draw whatever you want to draw with the camera.
batch.end();
// Finished drawing, get pixmap.
Pixmap pixmap = ScreenUtils.getFrameBufferPixmap(0, 0, width, height);
//Stop drawing to your fbo.
fbo.end();
}
After getting the pixmap you can iterate through the pixels and set the alpha of the pixels outside your green selection window to 0 making them invisible or "cutting them off"

Image and Canvas coordinate displacement when drawing

I am drawing lines on Canvas of SurfaceView which is in FrameLayout. I receive image from camera preview, process it, get coordinates of rectangles and raw the lines of it on canvas. I get a displacement of those lines in y axis when drawn, the lower the line is, the bigger displacement occurs (see photos below):
With red line I marked (with Paint program, not the actual app) the approximate position of where the coordinates coordinates of lower line are on bitmap, and the lower green line of rectangle (placed by the actual app, drawn on canvas) along with red line shows, how much coordinates are displaced. The coordinates on top cannot cross the screen, but on the bottom they can- if the rectangle is low enough, lines come below the screen, but on top they do not (they should not do that on either of all 4 sides, because the given coordinates are never out of bitmap).
The drawing function looks like this:
public void DrawAllContours(List<Point[]> rectPoints, int ratio)
{
paint.setColor(Color.GREEN);
paint.setStrokeWidth(2.5f);
canvas = sh.lockCanvas();
canvas.drawColor(0, PorterDuff.Mode.CLEAR);
for (int i = 0; i < rectPoints.size(); i++)
{
for (int j = 0; j < 4; j++)
canvas.drawLine((float)rectPoints.get(i)[j].x*ratio, (float)rectPoints.get(i)[j].y*ratio,
(float)rectPoints.get(i)[(j+1)%4].x*ratio, (float)rectPoints.get(i)[(j+1)%4].y*ratio, paint);
}
sh.unlockCanvasAndPost(canvas);
}
The ratio variable is the difference between the actual preview image size and resized bitmap for processing size (usualy the value is 3). The actual coordinates are as they should be on preview bitmap, but not on Canvas.
How can I overcome this issue and place lines on their exact places?
Thank you in advance.
So I found out, that camera preview size does differ from the canvas size. My preview size was 1920X1080, and canvas 1845X1080 or so, so thats why Y coordinate was displaced. I just found out the difference ratio and drew lines respectively by that ratio. Canvas resolution can be found with Canvas.getWidth(), Canvas.getHeight().

Android Bitmap: Convert transparent pixels to a color

I have an Android app that loads an image as a bitmap and displays it in an ImageView. The problem is that the image appears to have a transparent background; this causes some of the black text on the image to disappear against the black background.
If I set the ImageView background to white, that sort of works, but I get ugly big borders on the image where it is stretched to fit the parent (the actual image is scaled in the middle).
So - I want to convert the transparent pixels in the Bitmap to a solid colour - but I cannot figure out how to do it!
Any help would be appreciate!
Thanks
Chris
If you are including the image as a resource, it is easiest to just edit the image yourself in a program like gimp. You can add your background there, and be sure of what it is going to look like and don't have use to processing power modifying the image each time it is loaded.
If you do not have control over the image yourself, you can modify it by doing something like, assuming your Bitmap is called image.
Bitmap imageWithBG = Bitmap.createBitmap(image.getWidth(), image.getHeight(),image.getConfig()); // Create another image the same size
imageWithBG.eraseColor(Color.WHITE); // set its background to white, or whatever color you want
Canvas canvas = new Canvas(imageWithBG); // create a canvas to draw on the new image
canvas.drawBitmap(image, 0f, 0f, null); // draw old image on the background
image.recycle(); // clear out old image
You can loop through each pixel and check if it is transparent.
Something like this. (Untested)
Bitmap b = ...;
for(int x = 0; x<b.getWidth(); x++){
for(int y = 0; y<b.getHeight(); y++){
if(b.getPixel(x, y) == Color.TRANSPARENT){
b.setPixel(x, y, Color.WHITE);
}
}
}

How to scale text on a texture (quad object)?

I have found a good way to draw text in openGL by creating a Bitmap, drawing text on it, and making it into a texture.
I have screenCoordinates(320,~~480) and gameCoordinates(20,28), in which quads' dimensions are defined. Example constructor: GameObject(x, y, width, height, text).
To create the bitmap I create a Canvas with this size:
// get width and height in px (p is a Paint() object)
p.setTextSize(textSize * Main.getMainResources().getDisplayMetrics().density);
final int width = (int) p.measureText(text);
final int height = (int) (p.descent() + -p.ascent());
canvas.drawText(text, 0, -p.ascent(), p);
Create a bitmap of this, scaled to the next power of 2, and you have your texture-bitmap.
However the problem is that because the quad's dimensions are not adapted to the bitmap(text) dimensions, the text isn't very smooth. I have the possibility to change the quad's dimensions with quad.setDimensions(width, height), but what would be the size I'd have to give it, and also shouldn't I also have to worry about the textSize(sp) of the text i'm drawing?
This all is in 2D, and some simple math's might get involved, but how should I get the right dimensions?

Draw text in a Canvas and multiple lines

I'm starter with Canvas and Paint. I want to paint a text in a Canvas but it can be longer than the original Bitmap. So the text go out the Bitmap.
Is there some kind of automatic manager for this making a new line when the end is reached? or should I play with heights and distances? Thanks
yes, you can manage this with a StaticLayout or DynamicLayout
The best way is to draw text with StaticLayout:
// init StaticLayout for text
StaticLayout textLayout = new StaticLayout(
gText, paint, textWidth, Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);
// get height of multiline text
int textHeight = textLayout.getHeight();
// get position of text's top left corner
float x = (bitmap.getWidth() - textWidth)/2;
float y = (bitmap.getHeight() - textHeight)/2;
// draw text to the Canvas center
canvas.save();
canvas.translate(x, y);
textLayout.draw(canvas);
canvas.restore();
See my blogpost for more details.
I would suggest that you also look at this code snippet found here:
https://stackoverflow.com/a/15092729/1759409
As it will manage the writing of your text within a certain width and height and automatically draws onto the canvas correctly.

Categories

Resources