Row and column skipping is available in API 33. Shared source codes didn't work correct. Smooth rescaling is not a practial algorithm for dynamic game graphics. This algorithm is useful with pre-defined graphics. If there is a finder, share it please.
Edit: Mosaic rescale algorithm is here for Bitmap
objects:
UnpackedColor.java
import java.util.Random;
import android.graphics.Color;
import java.lang.Math;
public class UnpackedColor {
public float A, R, G, B;
public UnpackedColor(
float A,
float R,
float G,
float B
) {
this.A = A;
this.R = R;
this.G = G;
this.B = B;
}
public UnpackedColor(int packedColor) {
A = Color.alpha(packedColor) / 255f;
R = Color.red(packedColor) / 255f;
G = Color.green(packedColor) / 255f;
B = Color.blue(packedColor) / 255f;
}
public void sum(UnpackedColor ref) {
if (ref == null) return;
A += ref.A;
R += ref.R;
G += ref.G;
B += ref.B;
}
public void div(float divider) {
A /= divider;
R /= divider;
G /= divider;
B /= divider;
}
public void pow(float value) {
A *= value;
R *= value;
G *= value;
B *= value;
}
public int pack() {
int Ar = Math.round(255 * A);
int Rr = Math.round(255 * R);
int Gr = Math.round(255 * G);
int Br = Math.round(255 * B);
if (Ar > 255) Ar = 255;
else if (Ar < 0) Ar = 0;
if (Rr > 255) Rr = 255;
else if (Rr < 0) Rr = 0;
if (Gr > 255) Gr = 255;
else if (Gr < 0) Gr = 0;
if (Br > 255) Br = 255;
else if (Br < 0) Br = 0;
return Color.argb(Ar, Rr, Gr, Br);
}
}
Rescale.java
import android.graphics.Bitmap;
import java.lang.Math;
public class Rescale {
public static Bitmap filterBitmap(Bitmap refBitmap, float ratio) {
int newWidth = Math.round(refBitmap.getWidth() * ratio);
int newHeight = Math.round(refBitmap.getHeight() * ratio);
if (newWidth <= 0) {
newWidth = 1;
}
if (newHeight <= 0) {
newHeight = 1;
}
return Rescale.filterBitmap(refBitmap, newWidth, newHeight);
}
public static Bitmap filterBitmap(Bitmap refBitmap, float widthRatio, float heightRatio) {
int newWidth = Math.round(refBitmap.getWidth() * widthRatio);
int newHeight = Math.round(refBitmap.getHeight() * heightRatio);
if (newWidth <= 0) {
newWidth = 1;
}
if (newHeight <= 0) {
newHeight = 1;
}
return Rescale.filterBitmap(refBitmap, newWidth, newHeight);
}
public static Bitmap filterBitmap(Bitmap refBitmap, int newWidth, int newHeight) {
int width = refBitmap.getWidth();
int height = refBitmap.getHeight();
Bitmap ret = Bitmap.createBitmap(
newWidth,
newHeight,
Bitmap.Config.ARGB_8888
);
int gridXPointer = 0;
float gridXPointerF = 0.0f;
float gridXPointerF2 = 0.0f;
float gridYPointerF = 0.0f;
float gridYPointerF2 = 0.0f;
UnpackedColor loopTmpColor = null;
UnpackedColor unpackedRetPixel = null;
float retWeight = 0.0f;
float tmpYWeight = 0.0f;
float tmpWeight = 0.0f;
float refXF = 0.0f;
float refYF = 0.0f;
float loopF = 0.0f;
float loop2F = 0.0f;
float loopFMod = 0.0f;
float loop2FMod = 0.0f;
int refXFInt = 0;
int refYFInt = 0;
float refXFMod = 0.0f;
float refYFMod = 0.0f;
float refXFFirstMod = 0.0f;
float loopFInt = 0.0f;
float loop2FInt = 0.0f;
for (int gridYPointer = 0; gridYPointer < newHeight; gridYPointer++) {
gridYPointerF = (gridYPointer * (float)height) / (float)newHeight;
gridYPointerF2 = ((gridYPointer + 1) * (float)height) / (float)newHeight;
gridXPointer = 0;
for (; gridXPointer < newWidth; gridXPointer++) {
unpackedRetPixel = new UnpackedColor(
0.0f,
0.0f,
0.0f,
0.0f
);
gridXPointerF = (gridXPointer * (float)width) / (float)newWidth;
gridXPointerF2 = ((gridXPointer + 1) * (float)width) / (float)newWidth;
retWeight = 0.0f;
refYF = gridYPointerF;
refYFMod = refYF % 1.0f;
loopF = gridYPointerF2;
loop2F = gridXPointerF2;
loopFMod = loopF % 1.0f;
loop2FMod = loop2F % 1.0f;
loopFInt = (int)loopF;
loop2FInt = (int)loop2F;
retWeight = 0;
for (; refYF < loopF; refYF += 1.0f) {
refYFInt = (int)refYF;
if (refYFInt == loopFInt) {
tmpYWeight = loopFMod - refYFMod;
}
else if (refYFMod > 0.0f) {
tmpYWeight = 1.0f - refYFMod;
}
else {
tmpYWeight = 1.0f;
}
refXF = gridXPointerF;
refXFMod = refXFFirstMod;
for (; refXF < loop2F; refXF += 1.0f) {
refXFInt = (int)refXF;
loopTmpColor = new UnpackedColor(
refBitmap.getPixel(
refXFInt,
refYFInt
)
);
tmpWeight = tmpYWeight;
if (refXFInt == loop2FInt) {
tmpWeight *= loop2FMod - refXFMod;
}
else if (refXFMod > 0.0f) {
tmpWeight *= 1.0f - refXFMod;
}
else {
tmpWeight *= 1.0f;
}
loopTmpColor.pow(tmpWeight);
unpackedRetPixel.sum(loopTmpColor);
retWeight += tmpWeight;
if (refXFMod > 0.0f) {
refXF = refXFInt;
refXFMod = 0.0f;
}
}
if (refYFMod > 0.0f) {
refYF = refYFInt;
refYFMod = 0.0f;
}
}
unpackedRetPixel.div(retWeight);
ret.setPixel(
gridXPointer,
gridYPointer,
unpackedRetPixel.pack()
);
}
}
return ret;
}
}
Using the filter:
Bitmap b = ((BitmapDrawable)getResources().getDrawable(R.mipmap.icon)).getBitmap();
b = Rescale.filterBitmap(b, 0.75f);
//Or
b = Rescale.filterBitmap(b, 0.75f, 1.25f);
//Or
b = Rescale.filterBitmap(b, 250, 500);