I have an image where
Height = 1300
Width = 1300
I scaled the image to:
ScaledHeight = 700
ScaledWidth = 700
I am using the following to get the original Coordinates:
public Coordinate GetScaledXYCoordinate(int oldX, int oldY, int width, int height, int scaledWidth, int scaledHeight)
{
int newX = (int)(oldX * width)/scaledWidth;
int newY = (int)(oldY * height)/scaledHeight;
Coordinate retXY = new Coordinate(newX, newY);
return retXY;
}
EDIT:
I have updated to include answer
With
int width = 1300;
int scaledWidth = 700;
the value of (width/scaledWidth) is 1 - you are doing integer arithmetic not floating point.
Use
int newX = (oldX * width) /scaledWidth;
int newY = (oldY * height) /scaledHeight;
to avoid this issue.
Related
I am looking to rotate an image that is loaded from files by 90 degrees. I have the code but when I use it, I am given an error saying that the coordinates are out of bounds. Any help would be appreciated.
Here is the method I have written so far:
public void rotateImage(OFImage image) {
if (currentImage != null) {
int width = image.getWidth();
int height = image.getHeight();
OFImage newImage = new OFImage(width, height);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
Color col = image.getPixel(i, j);
newImage.setPixel(height - j - 2, i, col);
}
}
image = newImage;
}
}
When you rotate the image by a certain angle, the resulting image becomes larger than the original one. The maximum image size is obtained when rotated by 45 degrees:
When creating a new image, you have to set its dimensions according to the rotated size:
public BufferedImage rotateImage(BufferedImage image, double angle) {
double radian = Math.toRadians(angle);
double sin = Math.abs(Math.sin(radian));
double cos = Math.abs(Math.cos(radian));
int width = image.getWidth();
int height = image.getHeight();
int nWidth = (int) Math.floor((double) width * cos + (double) height * sin);
int nHeight = (int) Math.floor((double) height * cos + (double) width * sin);
BufferedImage rotatedImage = new BufferedImage(
nWidth, nHeight, BufferedImage.TYPE_INT_ARGB);
// and so on...
return rotatedImage;
}
See also: Rotate a buffered image in Java
I want to draw image on Top in each Arc of Canvas
private void drawImage(Canvas canvas, float tempAngle, Bitmap bitmap,String mValue) {
//get every arc img width and angle
int imgWidth = (radius / mWheelItems.size());
//int imgWidth = (radius / 3);
float angle = (float) ((tempAngle + 360 / mWheelItems.size() /2) * Math.PI / 180);
//calculate x and y
int x = (int) (center + radius / 2 / 2 * Math.cos(angle));
int y = (int) (center + radius / 2 / 2 * Math.sin(angle));
int top=y - imgWidth/2;
int bottom=y +imgWidth/2;
int left=x - imgWidth /2;
int right=x + imgWidth / 2;
Rect rect = new Rect(left, top, right, bottom);
final Rect rect1 = new Rect(x - imgWidth /2 , y - imgWidth / 2 , bitmap.getWidth() , bitmap.getHeight());
canvas.drawBitmap(bitmap, null, rect, null);
}
the Arc is made according to the size of items
The Result is shown like that
But I want the image bitmap shown on top like that of rect. Red also want to large size of images or bitmap
Solved by Specific Tab and Big Screen Tablets
Change the X and Y coordination According to Angle
if(tempAngle==0) {
x = x + 50;
}
if(tempAngle==60) {
y = y + 50;
}
if(tempAngle==120) {
imgWidth = imgWidth-12;
y = y + 20;
x = x - 40;
}
if(tempAngle==180) {
imgWidth = imgWidth+12;
x = x - 50;
}
if(tempAngle==240) {
y = y - 50;
}
if(tempAngle==300) {
y = y - 20;
x = x + 40;
}
So I have a field where my image displays and my max height can be 375 and max width is 775. I want it to be as close to as one of these values as possible to get the maximum size while maintaining the aspect ratio This is what I came up with and it actually seems to work pretty well but I am thinking there is a better way I am not thinking of.
InputStream in = new ByteArrayInputStream(fileData);
BufferedImage buf = ImageIO.read(in);
int maxWidth = 775;
int maxHeight = 375;
int newWidth;
int newHeight;
float height = buf.getHeight();
float width = buf.getWidth();
float ratio = (float) 0.0;
if(height > maxHeight || width > maxWidth)
{
if (height > width)
{
ratio = (height/width);
}
else if(width > height)
ratio = (width/height);
while(height > maxHeight || width > maxWidth)
{
if (height > width)
{
height -= ratio;
width -= 1;
}
else if(width > height)
{
width -= ratio;
height -= 1;
}
}
}
newWidth = (int) width;
newHeight = (int) height;
// Call method to scale image to appropriate size
byte[] newByte = scale(fileData, newWidth, newHeight);
You know that you will use one of the two maxes (if you weren't the image could still be scaled up).
So it's just a problem of determining which. If this aspect ratio of the image is greater than your max area ratio, then width is your limiting factor, so you set width to max, and determine height from your ratio.
Same process can be applied for a smaller ratio
Code looks something like the following
float maxRatio = maxWidth/maxHeight;
if(maxRatio > ratio) {
width = maxWidth;
height = width / ratio;
} else {
height = maxHeight;
width = height * ratio;
}
I'm trying to scale an image in relation to the width/height. Here is my method:
private byte[] scaleImage(Bitmap image) {
byte[] image = new byte[]{};
int width= image.getWidth();
int height = image.getHeight();
int wh = width / height ;
int hw = height / width ;
int newHeight, newWidth;
if (width> 250 || height> 250) {
if (width> height) { //landscape-mode
newHeight= 250;
newWidth = Math.round((int)(long)(250 * wh));
Bitmap sizeChanged = Bitmap.createScaledBitmap(image, newWidth, newHeight, true);
int bytes = størrelseEndret.getByteCount();
ByteBuffer bb = ByteBuffer.allocate(bytes);
sizeChanged.copyPixelsFromBuffer(bb);
image = bb.array();
} else { //portrait-mode
newWidth = 250;
newHeight = Math.round((int)(long)(250 * hw));
...same
}
}
return image;
}
After that, I wrote some codes to convert the image from Bitmapto byte[] array, but after a Debug I noticed that I'm getting really weird values. For example:
width = 640, height = 480, but wh = 1, hw = 0, newHeight = 200 and newWidth = 200?! I simply don't understand why? what am I doing wrong? Any help or hints is very appreciate. Thanks, Carl
You're running into a problem of integer arithmetic, basically - you're performing a division to get a scaling factor, but as an integer - so for something like 640x480, the scaling factors would be 1 and 0, because 640/480 is 1, and 480/640 is 0.
Instead of handling this as (x1/y1)*y2, you can change it to (x1*y2)/y1 so that you perform the division afterwards. So long as you don't overflow the integer limit in the multiplication (unlikely here) it should be fine. So I'd rewrite your code as:
private byte[] scaleImage(Bitmap image) {
byte[] image = new byte[]{};
int width = image.getWidth();
int height = image.getHeight();
int newHeight, newWidth;
if (width > 250 || height > 250) {
if (width > height) { //landscape-mode
newHeight = 250;
newWidth = (newHeight * width) / height;
} else {
newWidth = 250;
newHeight = (newWidth * height) / width;
}
} else {
// Whatever you want to do here
}
// Now use newWidth and newHeight
}
(I would definitely separate the "calculating newWidth and newHeight" from "performing the scaling" if possible, to avoid repeated code.)
I need to put a random image inside a screen with given resolution (640x480, 1280x720, etc). I finished it in Java. In Android do not support the BufferedImage and Graphics2D, I wonder if there is a way to replace this code from Java to Android. Here is my code from Java:
public BufferedImage resizeImage(BufferedImage originalImage, int type){
BufferedImage resizedImage = new BufferedImage(screenWidth, screenHeight, type);
Graphics2D g = resizedImage.createGraphics();
int imgWidth = originalImage.getWidth();
int imgHeight = originalImage.getHeight();
int newImgWidth = 0;
int newImgHeight = 0;
int X = 0;
int Y = 0;
if (imgWidth > screenWidth){
// scale width to fit
newImgWidth = screenWidth;
//scale height to maintain aspect ratio
newImgHeight = (newImgWidth * imgHeight) / imgWidth;
}
if (newImgHeight > screenHeight) {
//scale height to fit instead
newImgHeight = screenHeight;
//scale width to maintain aspect ratio
newImgWidth = (newImgHeight * imgWidth) / imgHeight;
}
if (imgWidth < screenWidth && imgHeight < screenHeight) {
X = screenWidth/2 - imgWidth/2;
Y = screenHeight/2 - imgHeight/2;
g.drawImage(originalImage, X, Y, imgWidth, imgHeight, null);
g.dispose();
return resizedImage;
}
X = screenWidth/2 - newImgWidth/2;
Y = screenHeight/2 - newImgHeight/2;
g.drawImage(originalImage, X, Y, newImgWidth, newImgHeight, null);
g.dispose();
return resizedImage;
}
Thank you in advance!