In my code I need create a Bitmap using double values. It´s important use the correct value.
I´m using:
Bitmap bmp = Bitmap.createBitmap(int, int, Bitmap.Config.ARGB_8888);
... When i would need something like:
Bitmap bmp = Bitmap.createBitmap(double, double, Bitmap.Config.ARGB_8888);
Everything I've trying to make the conversion ( possible ? ) Only returns the initial value or integer
How I can use double values when creating the bitmap?
Perhaps I misunderstand the question, but bitmaps are rasters of whole pixels. You can't have fractions of pixels, so you can only have integer numbers of rows and columns in the parameters for createBitmap.
Having said that, you can rescale how the bitmap is drawn using float scale factors applied via Matrix drawBitmap methods, e.g.
Canvas.drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)
Matrix matrix = new android.graphics.Matrix();
matrix.postScale(3.14f, 3.14f);
canvas.drawBitmap(bitmap, matrix, paint);
However, when it comes to rendering this on screen, it will again draw only whole pixels, so you still don't get fractional pixels displayed.
Try this, convert double to int:
double myDouble = 10.4;
int myInt = (int) (myDouble);
Using (int) casts the double into an int
Related
I'm trying to create a simple translational movement for a Bitmap object. I'm doing this by creating a canvas and passing a framebuffer to it, which had previously been initialized to a resolution of 1080/1920. I then proceeding to draw a bitmap with a call to canvas' method drawBitmap() like so:
this.canvas = new Canvas(frameBuffer);
...
canvas.drawBitmap(bitmap, null, destinationRect, paint);
In a different thread which is set as the Content View for the main activity I'm scaling the framebuffer to fit the actual screen size and then draw it with all its contents with these lines:
Canvas canvas = holder.lockCanvas();
canvas.getClipBounds(dstRect);
...
canvas.drawBitmap(framebuffer, null, dstRect, paint);
holder.unlockCanvasAndPost(canvas);
This results in very poor performance, both measuring manually with delta time and by monitoring with the Android Studio tools. Even visually you can see a trailing after the bitmap accompanied with very low fps.
I can't seem to find the cause of this, but I suspect that the scaling process that drawBitmap executes implicitly is doing something heavy. I tried changing the filter settings without success. I also doubt that I should head for openGL for this simple need.
Should I use bitmaps with different sizes and decide on runtime what size is the closest to my need or is there a more straightforward solution to this problem?
EDIT:
Here's how I gain a few more frames per second with the matrix.postScale() method:
int width = framebuffer.getWidth();
int height = framebuffer.getHeight();
float scaleWidth = ((float) game.size.x) / width;
float scaleHeight = ((float) game.size.y) / height;
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth, scaleHeight);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(framebuffer, 0, 0, width, height, matrix, true);
canvas.drawColor(Color.parseColor("#013501"));
canvas.drawBitmap(resizedBitmap, null, dstRect, paint);
holder.unlockCanvasAndPost(canvas);
I have bitmap that need to draw to canvas. The image is of a fixed size, but the canvas will change according to the user's screen size and density (bitmap coule be larger/smaller than the canvas).
I need to draw the bitmap to canvas scaling all the way into the canvas size (without distorting the image), I have done the code as below but the bitmap still filling only a portion of the screen.
Rect dest = new Rect(0, 0, drawCanvas.getWidth(), drawCanvas.getHeight());
Paint paint = new Paint();
paint.setFilterBitmap(true);
drawCanvas.drawBitmap(canvasBitmap, null, dest, paint);
May I know if anybody can shed light on a good solution? Thanks.
This example is in javascript but it should still help you out scale an image
jsFiddle : https://jsfiddle.net/CanvasCode/7oghuwe2/3/
javascript
var canvas1 = document.getElementById('canvas1');
var context1 = canvas1.getContext('2d')
var canvas2 = document.getElementById('canvas2');
var context2 = canvas2.getContext('2d');
var image1 = new Image();
image1.src = "http://media.giphy.com/media/iNk83OBPzlA8o/giphy.gif";
image1.onload = function () {
context1.fillStyle = "#F00";
context1.fillRect(0, 0, canvas1.width, canvas1.height);
context2.fillStyle = "#00F";
context2.fillRect(0, 0, canvas2.width, canvas2.height);
ratio(context1, canvas1, image1);
ratio(context2, canvas2, image1);
}
function ratio(context1, canvas1, image1) {
var imageRatio = image1.width / image1.height;
var newHeight = canvas1.width / imageRatio;
var newWidth = canvas1.height * imageRatio;
var heightDiff = newHeight - canvas1.height;
var widthDiff = newWidth - canvas1.width;
if (widthDiff >= heightDiff) {
context1.drawImage(image1, 0, 0, canvas1.width, canvas1.width / imageRatio);
} else {
context1.drawImage(image1, 0, 0, canvas1.height * imageRatio, canvas1.height);
}
}
Basically you need to calculate what the width would be if you scaled the image by the canvas height and what the height would be if you scale the image by the canvas width, and which ever is smaller, then you scale by that dimension.
The reason why it might not work for you might be because the function drawBitmap() ignores the density of the bitmap. The following is from the documentation.
public void drawBitmap (Bitmap bitmap, Rect src, Rect dst, Paint
paint)
This function ignores the density associated with the bitmap. This is
because the source and destination rectangle coordinate spaces are in
their respective densities, so must already have the appropriate
scaling factor applied.
What you could do is use public void drawBitmap (Bitmap bitmap, Matrix matrix, Paint paint) instead. First you need to map the source Matrix with the desination Matrix. You do this via Matrix.setRectToRect() or Matrix.setPolyToPoly(). This will give you an accurate mapping. Just make sure you map them correctly, otherwise things will be distorted.
For more info refer here: What code should I use with 'drawMatrix.setPolyToPoly' to manipulate and draw just a rectangular part of a bitmap, rather than the entire bitmap?
The mentioned class has got the following method:
protected void drawCompass(Canvas canvas, float bearing) {
int offset = Math.max(canvas.getHeight(), canvas.getWidth()) / 8;
Rect r = new Rect(0, 0, 2*offset, 2*offset);
canvas.drawBitmap(compassBase, null, r, paint);
canvas.rotate(-bearing, offset, offset);
canvas.drawBitmap(compassArrow, null, r, paint);
}
Link to the complete src: MyLocationOverlay
There they create a Rect r witch specifies where the both Bitmaps should be drawn on the canvas.
The java doc of drawBitmap says :"Draw the specified bitmap, scaling/translating automatically to fill the destination rectangle. If the source rectangle is not null, it specifies the subset of the bitmap to draw. "
Because both Bitmaps use the same Rect r and because they both are automatically scaled to fit the Rect, why is the result a perfect Compass when I activate the compass in the MapView.
To my mind the result should be crap, because the arrow of the compass is also scaled to fit the Rect.
So where is the error in reasoning?
They are scaled using the same proportion, not to absolute size. To answer your question, the canvas is drawn on using the bitmap as reference - think of it like a painter and a canvas painting one image on top of the other using two photo images as reference.
I'm working on an app that needs to apply perspective distortion correction to a photo taken with the phone's camera.
Once the photo is taken, the idea is to show it on an imageview and let the user mark the four corners of the document (a card, a sheet of paper, etc.) and then apply the correction based on those points.
This is an example of what im trying to achieve:
http://1.bp.blogspot.com/-ro9hniPj52E/TkoM0kTlEnI/AAAAAAAAAbQ/c2R5VrgmC_w/s640/s4.jpg
Any ideas on how to do this on android?
You don't have to use a library for this.
You can just as well use one of the drawBitmap functions of the Canvas class with a matrix that's initialized using the setPolyToPoly function of the Matrix class.
public static Bitmap cornerPin(Bitmap b, float[] srcPoints, float[] dstPoints) {
int w = b.getWidth(), h = b.getHeight();
Bitmap result = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
Canvas c = new Canvas(result);
Matrix m = new Matrix();
m.setPolyToPoly(srcPoints, 0, dstPoints, 0, 4);
c.drawBitmap(b, m, p);
return result;
}
(The Paint object is only needed to enable anti-aliasing.)
Usage:
int w = bitmap.getWidth(), h = bitmap.getHeight();
float[] src = {
0, 0, // Coordinate of top left point
0, h, // Coordinate of bottom left point
w, h, // Coordinate of bottom right point
w, 0 // Coordinate of top right point
};
float[] dst = {
0, 0, // Desired coordinate of top left point
0, h, // Desired coordinate of bottom left point
w, 0.8f * h, // Desired coordinate of bottom right point
w, 0.2f * h // Desired coordinate of top right point
};
Bitmap transformed = cornerPin(bitmap, src, dst);
Where src are the coordinates of the source points, dst are the coordinates of the destination points. Result:
What you want to do goes under various names of art, "corner-pin" being the one commonly used in the visual effects industry. You need to proceed in two steps:
Compute the mapping from the the desired, rectified image, to the original, distorted, image
Actually warp the original image according to the mapping computed in (1).
The 4 (non-collinear, perspective-distorted) corners of the original image, and the 4 corners of the target (undistorted) image, define the mapping. This mapping is called a "homography" - read the pointed wikipedia page for details. Once the mapping is known, the warping at step (2) can be computed by interpolation: for every pixel in the target image, find the corresponding pixel in the original image. As this will typically not be at integer coordinates, you interpolate its color from the neighbors. Various interpolation schemes are used, the common ones being nearest-neighbor, bilinear and bicubic (in increasing order of smoothness in the results).
For Android, I'd recommend installing the OpenCV SDK , and then use the geometry transformation routines (getPerspectiveTransform and warpPerspective for the two steps above).
In My application i use canvas to do paint.
Now in this application i want to Draw the Little small logo image at the right-bottom corner of the canvas before saving it in to Bitmap.
So how to make it possible ?
If I understand you correctly, try
context.drawImage(img_elem, x, y);
to insert your image (where img_elem is your image reference and x/y are your destination coordinates).
To use x and y, depending where you wish to insert the image, try something like:
x = canvasWidth-25;
y = canvasHeight-25;
To place it in the bottom right corner.
Then, convert to an image as per normal:
var dataURL = canvas.toDataURL();
After Some googling and searching for code, i got the answer of my question:
I Use this function to got the Image at the right-bottom corner.
public static Bitmap addLogo(Bitmap mainImage, Bitmap logoImage) {
Bitmap finalImage = null;
int width, height = 0;
width = mainImage.getWidth();
height = mainImage.getHeight();
finalImage = Bitmap.createBitmap(width, height, mainImage.getConfig());
Canvas canvas = new Canvas(finalImage);
canvas.drawBitmap(mainImage, 0,0,null);
canvas.drawBitmap(logoImage, canvas.getWidth()-logoImage.getWidth() ,canvas.getHeight()-logoImage.getHeight() ,null);
return finalImage;
}
Hope this code help to anyother.
Thanks.