Why am I getting a weird results from my scaleImage method?

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

Jon Skeet
people
quotationmark

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.)

people

See more on this question at Stackoverflow