// Need external definition of: scaleX, scaleY // We compress horizontally first, then vertically // which I think may be the fastest way. // // Up to scaleX-1 pixel columns and scaleY pixel rows may be discarded // (those not fitting in a scaleX*scaleY block). The discarded pixels are // along the right and bottom border of the image, respectively. int w, h, w2, h2; int[] horizontallyScaledPixels, finalPixels; void scaleHorizontally(BufferedImage img) { scaleHorizontally(grabbableIntPixels(img)); } void scaleHorizontally(GrabbableIntPixels gp) { w = gp.w; int h = this.h = gp.h; int w2 = this.w2 = w/scaleX, h2 = this.h2 = h/scaleY; int[] newPixels = horizontallyScaledPixels = new int[w2*h]; int iRow = gp.offset, iOut = 0; int[] pixels = gp.data; for (int y = 0; y < h; y++) { int iIn = iRow; for x to w2: { int r = 0, g = 0, b = 0; for subX to scaleX: { int rgb = pixels[iIn+subX]; r += (rgb >> 16) & 0xFF; g += (rgb >> 8) & 0xFF; b += rgb & 0xFF; } iIn += scaleX; newPixels[iOut++] = rgbIntFullAlpha(r/scaleX, g/scaleX, b/scaleX); } iRow += gp.scanlineStride; } // for y } void scaleVertically { int[] pixels = horizontallyScaledPixels; int[] newPixels = finalPixels = new int[w2*h2]; int iRow = 0, iOut = 0; for (int y = 0; y < h2; y++) { int iIn = iRow; for x to w2: { int r = 0, g = 0, b = 0; int iIn2 = iIn; for subY to scaleY: { int rgb = pixels[iIn2]; iIn2 += w2; r += (rgb >> 16) & 0xFF; g += (rgb >> 8) & 0xFF; b += rgb & 0xFF; } iIn++; newPixels[iOut++] = rgbIntFullAlpha(r/scaleX, g/scaleX, b/scaleX); } iRow += w2*scaleY; } // for y } BufferedImage get(BufferedImage img) { scaleHorizontally(img); scaleVertically(); ret get(); } BufferedImage get() { ret bufferedImage(w2, h2, finalPixels); }