How to make the simplest <div>-like transparent container/layer in AndEngine? - android

I would simply like to have an Entity, Rectangle or something that would serve as a plain container for other Sprites.
Positioning purposes is what I need it for... I need to be able to set this container's width and position.
I have tried with Rectangle, but it seems to hide absolutely everything behind it (with a lower Z-index).

you can change the alpha of the Rectangle to "see" what's underneath it. Something like
myRect = new Rectangle(x, (CAMERA_HEIGHT - 480 + 100) / 2, size, size, vboManager);
myRect.setAlpha(0);
scene.attachChild(myRect);

Related

How to get to edge pixel of an image

I'm trying to get the background color of image that I download with glide.
I think(please correct me if I'm wrong) that the best way is to get the edge pixel(top - left most, bottom - right most etc, my images are usually center image with solid background color)
I'm getting specific pixel color im my recycler view like this(based on the accepted answer here: How to Get Pixel Color in Android):
val bitmap = (binding.image.drawable as BitmapDrawable).bitmap
val pixel = bitmap.getPixel(x,y)
My question is how can I get the edge pixel of the image so I can determine the color of the background?
If you have the bitmap, you can use getWidth() and getHeight() (or just bitmap.width and bitmap.height in Kotlin) to get the X and Y coordinates of the far edges (it starts at 0 so it will be height - 1 etc).
Then you can plug those into getColor
with(bitmap) {
// origin (0,0) is the top left corner
val topLeft = getColor(0, 0)
val bottomRight = getColor(width-1, height-1)
....
}
(I used with to avoid going bitmap.whatever over and over)
This might not be the best way to get the actual background colour, it really depends (what if the image has a thin border?) and this could be a tricky problem! Just in case it helps, Android has the Palette library which lets you generate a bunch of colour swatches from a Bitmap, so that might be useful if you want to kind of pull out the main colours from an image and pick one

Using PixelCopy to copy a scaled View within a DialogFragment

I have a DialogFragment that creates an AlertDialog with a custom view in onCreateDialog. The custom view includes a spinning progress bar and a prompt as well as a large view (larger than screen dimensions) that is fit inside the custom content via scaleX and scaleY values.
I am using the PixelCopy API to copy only the large view into a bitmap. This works well, but with a rather annoying caveat:
I call PixelCopy as such:
val winloc = intArrayOf(0, 0)
view.getLocationOnScreen(winloc)
val offset = 0
val left = winloc[0] + offset
val top = winloc[1] + offset
val rect = Rect(left, top, left + view.measuredWidth, top + view.measuredHeight)
PixelCopy.request(getDialog().getWindow(), rect, bitmap, listener, view.handler)
The view.getLocationOnScreen(winloc) returns x and y coordinates of (84, 84)
When I check the generated bitmap, PixelCopy has captured a whole lot of frame, padding, shadows, and the actual view content (with a bit missing from bottom right). The part of the actual content that is missing is exactly the same amount as the frame, padding, and shadow that I get at the top left of the image.
Having tried anything else I could think of to get the correct bounds of this content I want to save, I started adding random values to the coordinates (the offset value above). On a Nexus 6P an offset of 112 was perfect. Now I can't just throw 112 in there without reason because 1. it's a magic number and 2. it only works on one device.
I have ran out of ideas as to how I can get the correct bounds for this view OR where I can find this 112 value so that I can properly offset what I have.
As the app is unreleased, I can't include actual screenshots, but here are some redacted screenshots (ignore the black bars).
Some notes about the screenshots:
The green part comes from dialog!!.window!!.setBackgroundDrawable(ColorDrawable(0xff00ff00.toInt())) so I could outline the window bounds. The transparent/shadow bit between the screen edges and the green rectangle ... is this a margin or padding?
The white rectangle with the red (content 1) and the blue (content 2) rectangles is the portion going to the bitmap
The red and the blue rectangles within the content are different views generated from the same data.
The blue portion contains a few SurfaceViews that I suspect I'd have to extract separately.
Device screenshot
Captured Bitmap (without the 112 magic number offset)
The solution so far has been to ditch the DialogFragment and use a regular Fragment. After inspecting the layouts, there were two paddings of 56 pixels, without any accessors to get their values. I suspect there's a bug somewhere in the private decor views that doesn't account for these paddings when calculating the location of the view in window.
I'll mark this as the answer until a better answer comes along.

How to make something appear on a specific location in an image?

I want to make something(for example an arrow) appear on a picture. The location of this arrow depends on the value in a variable. How do I make this in Android? If possible, I need it to be screensize-independent and also support zooming in. Thanks!
To draw an image at a specific place you should change its margins values:
MarginLayoutParams params= (MarginLayoutParams)getLayoutParams();
params.setMargins((int) Math.round(location.x - (_width / 2.0)),
(int)Math.round(location.y - (_height / 2.0)), 0, 0);
requestLayout();
width and height are you image dimensions.

How to draw circle with alpha gradient on canvas?

How to draw on canvas like this pic with alpha gradient?
Please specify next time whether you mean the android app canvas or HTML5 canvas on android browsers. If its the former, use android-canvas. This solution is in JS since its easier to show, and will work fine on either platform.
Gradients along paths in canvas are hard. The easiest way is to fudge it.
Instead of thinking of your image as a gradient that follows a circular path, think of it as two linear gradients.
One on the left side, going from green to gray, top to bottom.
The other on the right side, going from white to gray, top to bottom.
Imagine a square made of those two gradients:
Now imagine a circle cutting through:
That's all you gotta do.
To "cut" through like that its easiest to use clipping regions, so I've made an example doing that.
Here's the live example: http://jsfiddle.net/simonsarris/Msdkv/
Code below:
var greenPart = ctx.createLinearGradient(0,0,0,100);
greenPart.addColorStop(0, 'palegreen');
greenPart.addColorStop(1, 'lightgray');
var whitePart = ctx.createLinearGradient(0,0,0,100);
whitePart.addColorStop(0, 'white');
whitePart.addColorStop(1, 'lightgray');
var width = 20;
ctx.lineWidth = width;
// First we make a clipping region for the left half
ctx.save();
ctx.beginPath();
ctx.rect(-width, -width, 50+width, 100 + width*2);
ctx.clip();
// Then we draw the left half
ctx.strokeStyle = greenPart;
ctx.beginPath();
ctx.arc(50,50,50,0,Math.PI*2, false);
ctx.stroke();
ctx.restore(); // restore clipping region to default
// Then we make a clipping region for the right half
ctx.save();
ctx.beginPath();
ctx.rect(50, -width, 50+width, 100 + width*2);
ctx.clip();
// Then we draw the right half
ctx.strokeStyle = whitePart;
ctx.beginPath();
ctx.arc(50,50,50,0,Math.PI*2, false);
ctx.stroke();
ctx.restore(); // restore clipping region to default

Android Screen Ratios

I'm using OpenGL ES 2.0 on Android and I and I initialise my display like so:
float ratio = (float) width / height;
Matrix.orthoM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7); //Using Orthographic as developing 2d
What I'm having trouble understanding is this:
Let's say my app is a 'fixed screen' game (like Pac-Man ie, no scrolling, just the whole game visible on the screen).
Now at the moment, if I draw a quad at -1 to +1 on both x and y I get something like this:
Obviously, this is because I am setting -ratio, ratio as seen above. So this is correct.
But am I supposed to use this as my 'whole' screen? With rather massive letterboxing on the left and right?
I want a rectangular display that is the whole height of the physical display (and as much of the width as possible), but this would mean drawing at less that -1 and more than +1, is this a problem?
I realise the option may be to use clipping if this was a scrolling game, but for this particular scenario I want the whole 'game board' on the screen and to be static (And to use as much of the available screen real estate as possible without 'stretching' thus causing elongation of my sprites).
As I like to work with 0,0 as the top of the screen, basically what I do is pass my draw method something like so:
quad1.drawQuad (10,0);
When the drawQuad method get's this, it basically takes the range from left to right as expressed my openGL and divide the the screen width (so, in my case -1.7 through +1.7 so 3.4/2560 = 0.001328125). And say I specify 10 as my X (as above), it will say something like:
-1.7 + (10*0.001328125) = -1.68671875
It then plots the quad at -1.68671875.
Doing this I am able to work with normal co-ords (and I just subtract rather than add for y axis so I can have 0 at the top).
Is this a good way to do things?
Because with this method, at the moment, if I specify a 100,100 square, it isn't a square, it's rectangle. However, on the plus side, I can fill the whole physical screen by scaling the quad by width x height.
You are drawing a 1x1 quad, so that is why you see a 1x1 quad. Try translating the quad 0.25 to the right or left and you will see that you can draw in that space too.
In graphics, you create an object, like a quad, in your case you made it 1x1. Then you position it wherever you want. If you do not position it, then it will be at the origin, which is what you see.
If you draw a wider shape, you will also see you can draw outside this area on the screen.
By the way, with your ortho matrix function, you aren't just specifying the screen aspect ratio, you are also specifying the coordinate unit size you have to work with. This is why a 1x1 is filling the height the of the screen, because your upper and lower boundaries are set to 1 and -1. Your ratio is a little more than one, since your width is longer than your height, so your left and right boundaries are essentially something like -1.5 and 1.5 (whatever your ratio happens to be).
But you can also do something like this;
Matrix.orthoM(mProjMatrix, 0, -width/2, width/2, -height/2, height/2, 3, 7);
Here, your ratio is the same, but you are sending it to your ortho projection with screen coordinates. (Disclaimer: I don't use the same math library you do, but these appears to be a conventional ortho matrix function based on the arguments you are passing to it).
So lets say you have a 1000x500 pixel resolution. In OpenGL your origin of 0,0 is in the middle. So now your left edge is at (-500,y), right edge at (500,y) and your top is (x,250). So if you draw your 1x1 quad, it will be very tiny, but if you draw a 250x250 square, it will look like your 1x1 quad in your previous ortho projection.
So you can specify the coordinates you want, the ratio, the unit size, etc for how you want to work. Personally, I dont't like specifying coordinates as fractions between 0 and 1, I like to think about them in the same sense as the screen pixels.
But whether or not you choose to do this, hopefully you understand what you are actually passing to these matrix functions.
One of the best ways to learn is draw an object to the screen and just play around with different numbers you send to your modelview and projection matrices so you can see what it is they are actually doing.

Categories

Resources