How to fix cutted/trimmed side on canvas/bitmap? - java

Im trying to merge to bitmap using this code
Bitmap bitmapMerged = Bitmap.createBitmap(
w, h,
bitmapOriginal.getConfig());
Canvas canvasMerged = new Canvas(bitmapMerged);
canvasMerged.drawBitmap(bitmapOriginal, 0, 0, null);
canvasMerged.drawBitmap(bitmapSecond, bitmapOriginal.getWidth(), 0, null);
It merge successfully, my next goal is to rotate the merged bitmap so I used this code
Matrix matrix = new Matrix();
matrix.postRotate(10);
canvasMerged.setMatrix(matrix);
But the image is cutted/trim the side it seems it didnt fit in how to fix this?

Use matrix.postRotate(); with center. So,
matrix.postRotate( 10, centerX, centerY );

Related

Draw a circle partially filled dynamically

I'm trying to play with canvas. I could draw some triangles and fill it partially drawing a path and paint it.I used Path, Points and Line. It was a great exercise to remember trigonometry. For now I would like to do the same with a circle, as you can see below. I want set a percentage and to fill this circle until the circle's height * percentage. How could me draw a circle like that with canvas or some lib?
You should think about it a little differently. The way I'd do it is to draw a coloured rectangle (where the height is a percentage of the circle's intended height) and then crop it with a circle. This answer explains how to crop an image in a circular shape (I'd rather link than retype the code here).
I finally got do it. I created two methods. As roarster suggested, I created a white rectangle as mask where the height is a percentage of the circle's intended height.
private Bitmap drawWithPorterDuff(Bitmap original, Bitmap mask, PorterDuff.Mode mode) {
Bitmap bitmap = Bitmap.createBitmap(original.getWidth(), original.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Paint maskPaint = new Paint();
maskPaint.setAntiAlias(true);
canvas.drawBitmap(original, 0, 0, null);
maskPaint.setXfermode(new PorterDuffXfermode(mode));
canvas.drawBitmap(mask, 0, 0, maskPaint);
Bitmap edge = BitmapFactory.decodeResource(getResources(), R.drawable.edge);
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD));
canvas.drawBitmap(edge, 0, 0, maskPaint);
return bitmap;
}
public Bitmap createMask(int width, int height) {
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.WHITE);
paint.setAntiAlias(true);
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawRect(0, 0, width, height, paint);
return bitmap;
}
At view's constructor I created a init() method with the folling code
PorterDuff.Mode mode = PorterDuff.Mode.SRC_IN;
Bitmap original = BitmapFactory.decodeResource(getResources(), R.drawable.blue_graph);
Bitmap mask = createMask(original.getWidth(), (int) ((original.getHeight()) * (1 - percentage)));
Bitmap result = drawWithPorterDuff(original, mask, mode);
imageView.setImageBitmap(result);

Apache PDFBox rotate PDImageXObject

I'm playing around with the 2.0.0-SNAPSHOT, and I want to set the page to landscape and also rotate my picture. So I've done page.setRotation(90);
There seems to be a bug with using PDFBox and AffineTransform
This code doesn't do anything like I'd expect:
AffineTransform at = new AffineTransform(w, 0, 0, h, 20, 20);
at.translate(0.5, 1);
at.rotate(Math.toRadians(90));
Width and Height have to be tiny to keep the image on the page, rotate by itself squishes the image, and translate before rotate seems to scale the image huge.
Is this a bug, or am I just not understanding PDFBox?
Don't do an extra translation, instead put the translation when creating the AT. Remember that the rotation is around the bottom-left axis, so add the width w to the x-position.
PDPage page = new PDPage();
document.addPage(page);
page.setRotation(90);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
int x = 150;
int y = 300;
// draw unrotated
contentStream.drawXObject(ximage, x, y, ximage.getWidth() / 2, ximage.getHeight() / 2);
// draw 90° rotated, placed on the right of the first image
AffineTransform at = new AffineTransform(ximage.getHeight() / 2, 0, 0, ximage.getWidth() / 2, x + ximage1.getWidth(), y);
at.rotate(Math.toRadians(90));
contentStream.drawXObject(ximage, at);
This will draw the image twice, once normally and once rotated 90°, and positioned to the right. "/2" is used to scale 50%, you can of course use another factor. Note that "/2" is not used for the initial x position, because the (scaled) width is needed twice. Once to position to the old position (because of the axis!), and once to move it to the right so that the images don't overlap.
Note also that getHeight() and getWidth() are reversed, for the page rotation.
AffineTransform at = new AffineTransform(w, 0, 0, h, 20, 20);
at.translate(0.5, 1);
at.rotate(Math.toRadians(90));
Width and Height have to be tiny to keep the image on the page, rotate by itself squishes the image, and translate before rotate seems to scale the image huge.
Is this a bug, or am I just not understanding PDFBox?
It is not a bug, it simply is math. You merely have to be aware that if you have an AffineTransform at and then call at.translate(...) or at.rotate(...), you do not set the translation / rotation part of the affine transformation to the given values but instead replace your transformation by the composition of the former transformation and the translation / rotation.
This means that e.g.
AffineTransform at = new AffineTransform(w, 0, 0, h, 20, 20);
at.translate(0.5, 1);
is not the same as
AffineTransform at = new AffineTransform(w, 0, 0, h, 20.5, 21);
as you might have expected, but instead
AffineTransform at = new AffineTransform(w, 0, 0, h, 20 + w/2, 20 + h);
This is why Width and Height have to be tiny to keep the image on the page - translate(0.5, 1) pushes very far otherwise.
As the order in which you compose the transformation matters, you might be happier if you created your transformation in this order:
AffineTransform at = AffineTransform.getTranslateInstance(0.5, 1);
at.rotate(Math.toRadians(90));
af.concatenate(new AffineTransform(w, 0, 0, h, 20, 20));
PS: As Tilman said: Remember that the rotation is around the bottom-left, so this composition will rotate off-screen, too. Simply add h+20 to the x coordinate of the initial translation.

How to rotate image at a specific point by a certain angle in java?

I want to rotate an image about a specific pixel position and not about the centre of the image. I want to rotate the image by certain degrees less than 90. I've made use of rotate function of the graphics class but i get the image blurred when rotated. How to remove this blur? Is there a specific function for this? This is the code i am using right now:
BufferedImage oldImage = ImageIO.read(new File("C:/omr/OMR_Rotation_1.jpg"));
BufferedImage newImage = new BufferedImage(oldImage.getWidth(), oldImage.getHeight(),oldImage.getType());
Graphics2D graphics = (Graphics2D) newImage.getGraphics();
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_DEFAULT);
graphics.rotate(Math.toRadians(-2.3), newImage.getWidth() / 2, newImage.getHeight() / 2);
graphics.translate((newImage.getWidth() - oldImage.getWidth()) / 2, (newImage.getHeight() - oldImage.getHeight()) / 2);
//graphics.drawImage(oldImage, 0, 0, oldImage.getWidth(), oldImage.getHeight(), null);
graphics.drawImage(oldImage, null, 0, 0);
ImageIO.write(newImage, "JPG", new File("C:/omr/OMR_Rotation_2.jpg"));
graphics.translate((newImage.getWidth() - oldImage.getWidth()) / 2, (newImage.getHeight() - oldImage.getHeight()) / 2);

How to offset bitmap, drawn on a canvas?

Here's my code that draws a BitmapMesh, as well as a circle on canvas.
canvas.drawBitmapMesh(GirlBitmap, WIDTH, HEIGHT, matrixVertsMoved, 0, null, 0, null); // need to offset this by "addOffset"
canvas.drawCircle(pointX+addOffset, pointY, bubbleSize, p3);
Both of which have to be offset by x by addOffset. It wors fine with the circle, but I can't figure out how to make the bitmap offset?
Any ideas? Maybe I should draw it on a separate canvas and then draw it on the old one, with an offset?
Thanks!
Can't you just translate the Canvas by (addOffset, 0)? Like this:
final int saveCount = canvas.save();
try {
canvas.translate(addOffset, 0);
canvas.drawBitmapMesh(GirlBitmap, WIDTH, HEIGHT, matrixVertsMoved, 0, null, 0, null);
canvas.drawCircle(pointX, pointY, bubbleSize, p3);
} finally {
canvas.restoreToCount(saveCount);
}

How to Draw a shape or bitmap into another Bitmap , Java/android

I want to draw a shape(many circles particularly) into a Specific Bitmap.
I have never used canvas / 2D graphs etc.
Anyone that can point me to the right direction to do what i want.?
#
As i see it i create a Drawable put the bitmap in it then "canvas-it" to the shapes i want etc
but i really need some guideline
OK i sorted it out
Bitmap b=BitmapFactory.decodeResource(CON.getResources(),R.drawable.deltio);
Bitmap bmOverlay = Bitmap.createBitmap(b.getWidth(), b.getHeight(), b.getConfig());
canvas = new Canvas(bmOverlay);
Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawBitmap(b, new Matrix(), null);
canvas.drawCircle(750, 14, 11, paint);

Categories