Может быть, этот код поможет вам:
/**
* @param bitmap Bitmap original
* @param finWid width of the new Bitmap (width of the cut)
* @param finHei height of the new Bitmap (height of the cut)
* @param angulo angle of rotation in degrees
* @param sx scale X
* @param sy scale Y
* @param tx Translate X
* @param ty Translate Y
* @param config {@link Config} of the new Bitmap
* @return {@link Bitmap} transformed
*/
public Bitmap createTransPixBitmap(Bitmap bitmap, int finWid, int finHei, float angulo, float sx, float sy, float tx, float ty, Config config){
return Bitmap.createBitmap(createTransPixArray(bitmap, bitmap.getWidth(), bitmap.getHeight(), finWid, finHei, angulo, sx, sy, tx, ty), finWid, finHei, config);
}
public int[] createTransPixArray(Bitmap bitmap, int width, int height, int finWid, int finHei, float angulo, float sx, float sy, float tx, float ty){
float scaWid = width*sx;
float scaHei = height*sy;
int[] ori = new int[width*height];
bitmap.getPixels(ori, 0, width, 0, 0, width, height);
bitmap.recycle();
bitmap = null;
System.gc();
return transformPix(ori, width, height, scaWid, scaHei, finWid, finHei, angulo, tx, ty);
}
/**
* Core function for apply scale, translate and rotation (cut the image if you want too)
* @param ori original color array
* @param wid original width
* @param hei original height
* @param scaWid scaled original width
* @param scaHei scaled original height
* @param finWid width of the new Bitmap
* @param finHei height of the new Bitmap
* @param angulo rotation in degrees
* @param tx Translate X
* @param ty Translate Y
* @return int[] of colors
*/
private int[] transformPix(int[] ori, int wid, int hei, float scaWid, float scaHei, int finWid, int finHei, float angulo, float tx, float ty){
int[] fin = new int[finWid*finHei];
double sin = Math.sin(Math.toRadians(angulo));
double cos = Math.cos(Math.toRadians(angulo));
int dx = (int)((scaWid-finWid)/2);
int dy = (int)((scaHei-finHei)/2);
/* No se como explicar esto, solo puedo decir que el proceso de escalado es en sentido inverso
* escala, rota, translada y corta, todo al mismo tiempo :D
*/
for(int y = 0; y < finHei; y++){
for(int x = 0; x < finWid; x++){
int tempX = (int)Math.floor(((x+dx-((float)scaWid/2))*((float)wid/scaWid))+0.5f-tx);
int tempY = (int)Math.floor(((y+dy-((float)scaHei/2))*((float)hei/scaHei))+0.5f-ty);
int tempRX = (int)Math.floor(((cos*(float)tempX)+(sin*(float)tempY))+0.5f+((float)wid/2));
int tempRY = (int)Math.floor(((cos*(float)tempY)-(sin*(float)tempX))+0.5f+((float)hei/2));
if((tempRX >= 0 && tempRX < wid) && (tempRY >= 0 && tempRY < hei))
fin[x+(y*finWid)] = ori[tempRX+(tempRY*wid)];
}
}
ori = null;
return fin;
}
Эта функция просто масштабирует массив цветов (если вам не нужны дополнительные функции):
private int[] scale(int[] ori, int wid, int hei, int finWid, int finHei){
int[] fin = new int[finWid*finHei];
for(int y = 0; y < finHei; y++){
for(int x = 0; x < finWid; x++){
int temp = (int)(x*(wid/finWid))+((int)(y*(hei/finHei))*wid);
fin[x+(y*finWid)] = ori[temp];
}
}
return fin;
}
Надеюсь, это будет полезно, и я с удовольствием буду благодарен за несколько советов по улучшению этого кода.