I want to translate matrix bitmap diagonally and it is translating as expected but it is repeating every time. I want to translate bitmpap only once after activity scrolling of this childview. Below is the code, could someone light me up where am I doing wrong.
Matrix matrix = new Matrix();
matrix.reset();
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.bitmap_image);
int TRANSLATE = 3000;
float diagonal = Math.sqrt(Math.pow((center / 2), 2) + Math.pow((center - padding / 2), 2));
float translate = (double) (System.currentTimeMillis() % TRANSLATE) / TRANSLATE * diagonal;
matrix.postTranslate((float) -bitmap.getWidth() / 2, (float) -bitmap.getHeight() / 2);
matrix.postTranslate((float) (center + padding - translate), (float) (center - padding + translate));
canvas.drawBitmap(bitmap, matrix, null);
Related
I want to scale the bitmap and translate that bitmap center of the screen(screen size not specified ).
I'm trying this way
Matrix matrix = new Matrix();
protected void setImageDrawableCenter(#NonNull Drawable imgDrawable,float sc) {
float width = getWidth();//this provide framelayout width
float height = getHeight();//this provide framelayout height
float offsetX = width - imgDrawable.getIntrinsicWidth();
float offsetY = height - imgDrawable.getIntrinsicHeight();
offsetY /= sc;
offsetX /= sc;
matrix.postTranslate(offsetX, offsetY);
float scaleFactor, widthScaleFactor, heightScaleFactor;
widthScaleFactor = (float) getWidth() / imgDrawable.getIntrinsicWidth();
heightScaleFactor = (float) getHeight() / imgDrawable.getIntrinsicHeight();
scaleFactor = widthScaleFactor > heightScaleFactor ? heightScaleFactor : widthScaleFactor;
matrix.postScale(scaleFactor / sc, scaleFactor / sc, getWidth() / sc, getHeight() / sc);
invalidate();
}
When calling the above function.
setImageDrawableCenter(imgDrawable,2); when scale is 2f is perfectly work.(note image size is 512x512)
setImageDrawableCenter(imgDrawable,1); when scale is 1.5f is image not set in center.
[More detail on this link. Line number : 720](https://github.com/wuapnjie/StickerView/blob/master/sticker/src/main/java/com/xiaopo/flying/sticker/StickerView.java#:~:text=protected%20void-,addStickerImmediately,-(%40NonNull)
The task is to crop video by given points(like rectangle) and display the cropped video.
The code works with cropping the first halh of video(0, 0, videoWidth/2, videoHeight). But when i tryed to display the second one(videoWidth/2, 0, videoWidth, videoHeight), that is what was displayed.
The video is displayed on TextureView inside FrameLayout.
The part, that doesn't work:
private void updateTextureViewSize(int ax, int ay, int bx, int by) {
float scaleX;
float scaleY;
//proportions between screen and frame dimensions
scaleX = mVideoWidth / mDisplayWidth;
scaleY = mVideoHeight / mDisplayHeight;
float scaleRegionW = mVideoWidth / Math.abs(ax - bx);
float scaleRegionH = mVideoHeight / Math.abs(ay - by);
float scaleRegion = scaleRegionW < scaleRegionH ? scaleRegionW : scaleRegionH;
Matrix matrix = new Matrix();
if (scaleX > scaleY) {
matrix.setScale(scaleRegion / scaleY, scaleRegion);
matrix.postTranslate(-ax * (int) scaleRegion / scaleY, -ay * scaleRegion / scaleY);
} else {
matrix.setScale(scaleRegion, scaleRegion / scaleX);
matrix.postTranslate(-ax * scaleRegion / scaleX, -ay * scaleRegion / scaleX);
}
mTextureView.setTransform(matrix);
mTextureView.setLayoutParams(new FrameLayout.LayoutParams((int) mDisplayWidth, (int) mDisplayHeight));
}
The answer was found by Dmitry Yacenko.
The full code.
An easy way to crop video by given points (ax, ay, bx, xy) is:
float scaleX = mDisplayWidth / mVideoWidth, scaleY = mDisplayHeight / mVideoHeight;
//proportions between screen and frame dimensions
float scale = mDisplayHeight / Math.abs(by - ay);
Matrix matrix = new Matrix();
matrix.reset();
matrix.setScale(scale / scaleX, scale / scaleY);
//scaling video
matrix.postTranslate(-scale * ax, -scale * ay);
//move video, so the needed part of it will be displayed properly
mTextureView.setLayoutParams(new FrameLayout.LayoutParams((int) mDisplayWidth, (int) mDisplayHeight));
mTextureView.setTransform(matrix);
//updating the Texture view
I am using the following texture
It is being displayed only partially and it gets repeated when I used the following code:
float scale = (float)( (float)Gdx.graphics.getWidth() / (float)(tex.getWidth()));
w = Gdx.graphics.getWidth();
h = scale * tex.getHeight();
float x = 0.0f;
float y = Gdx.graphics.getWidth() - h * splashTimer;
Sprite s = new Sprite(tex);
//s.setOriginCenter();
// s.setScale(scale);
//s.setOriginCenter();
// s.setOriginCenter();
//s.setSize(s.getWidth() * scale, s.getHeight() * scale);
//s.setOriginCenter();
s.setScale(0.1f);//1.0f + (1.0f - scale));
s.setOrigin(0, 0);
s.setPosition(x, y);
batch.begin();
batch.draw(s,0,0,Gdx.graphics.getWidth(), scale * s.getHeight());
// s.draw(batch);
batch.end();
It gets chopped and repeated in Android and looks like this:
Orange isn't even drawn. Why is this happening?
Apparently this happened because I was using mipmaps. I disabled the use of mipmaps and now it works.
in my project I want to draw my drawable to the screen to fit its height and width , and then I want to draw other things on its center . The problem is when I want to draw it , it not shows fit to the screen , I have tried many things but nothing work for me.
I know my question is not clear so shortly asking that how to fit the image to fit the background using canvas.drawmethod()
here is what I am using
final Drawable dial = mDial;
int w = dial.getIntrinsicWidth();
int h = dial.getIntrinsicHeight();
boolean scaled = false;
if (availableWidth < w || availableHeight < h) {
scaled = true;
float scale = Math.min((float) availableWidth / (float) w,
(float) availableHeight / (float) h);
canvas.save();
canvas.scale(scale, scale, x, y);
Log.d("Scaling the width and height","here we go");
}
if (changed) {
dial.setBounds(x - (w / 2), y - (h / 2), x + (w / 2), y + (h / 2));
Log.d("bounds have been changed","here we go");
}
dial.draw(canvas);
please help
I am creating a little game in Java and I have an image which gets rotated.
As you can see in the two images below, there is a giant ship which slowly rotates in the game, but when it gets to a certain point it gets cut off (due to its own little BufferedImage).
Heres my rendering code:
public void drawImageRotated(BufferedImage img, double x, double y, double scale, double angle) {
x -= xScroll;
y -= yScroll;
BufferedImage image = new BufferedImage((int)(img.getWidth() * 1.5D), (int)(img.getHeight() * 1.5D), 2);
Graphics2D g = (Graphics2D)image.getGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.rotate(Math.toRadians(angle), image.getWidth() / 2, image.getHeight() / 2);
g.drawImage(img, image.getWidth() / 2 - img.getWidth() / 2, image.getHeight() / 2 - image.getHeight() / 2, null);
g2d.drawImage(image, (int)(x-image.getWidth()*scale/2), (int)(y-image.getHeight()*scale/2), (int)(image.getWidth()*scale), (int)(image.getHeight()*scale), null);
g.dispose();
}
Back to the matter at hand, how can i work out the maximum x and y size of an image during rotation so I can compensate with my buffered images size?
If you have a basically rectangular image which is rotated around its center, the maximum width and height during rotation will be when a diagonal of the image rectangle is horizontal or vertical. This diagonal distance could be computed with the Pythagorean Theorem and used for the width and height of the BufferedImage.
int size = (int) Math.sqrt((img.getWidth() * img.getWidth()) + (img.getHeight() * img.getHeight()));
BufferedImage image = new BufferedImage(size, size, 2);
// The rest of your code as before
how can i work out the maximum x and y size of an image during rotation so I can compensate with my buffered images size?
double sin = Math.abs(Math.sin(angle));
double cos = Math.abs(Math.cos(angle));
int w = image.getWidth();
int h = image.getHeight();
int neww = (int)Math.floor(w*cos+h*sin);
int newh = (int)Math.floor(h*cos+w*sin);
The above code was taken from this example: Java(SWING) working with Rotation
An alternative is to rotate the actual Graphics object, draw the image, and restore the rotation:
AffineTransform old = g2d.getTransform();
g2d.rotate(Math.toRadians(angle), x + image.getWidth() / 2, y + image.getWidth() / 2);
g2d.drawImage(image, x, y, null);
g2d.setTransform(old);
Let's consider width being the width of the original image, height its original height and angle the rotation angle value in radians.
According to my calculations, the size of the rotated image is something like this:
rotatedWidth = Math.cos(angle) * width + Math.sin(angle) * height;
rotatedHeight = Math.sin(angle) * width + Math.cos(angle) * height;
You may also need to take a look at this thread as well, as it may help.