blackberry 图片缩放 整理代码

    技术2022-06-28  77

    最好使得时 双线性插值算法。

     

    代码原型基本上是网上淘的,另外自己整理的。若侵权请提示,哥们我就删贴~

     

    import javax.microedition.lcdui.Image; import net.rim.device.api.math.Fixed32; import net.rim.device.api.system.Bitmap; import net.rim.device.api.system.EncodedImage; import net.rim.device.api.system.PNGEncodedImage; public class ConstantUtil { public static Bitmap resizeBitmap(Bitmap image, int width, int height) { return rizeImageByBiliNearInterpolation(image, width, height); } // public static Bitmap resizeBitmap(String src, int width, int height) { // Bitmap image = Bitmap.getBitmapResource(src); // return rizeImageByBiliNearInterpolation(image, width, height); // } /** * 最邻近插值算法(貌似是这个算法) * @param image 需要缩放的图片 * @param width 缩放后的宽度 * @param height 缩放后的高度 * @return */ private static Bitmap rizeImageByNearestNeighborInterpolation (Bitmap image, int width, int height){ if (image == null ) return null ; int imageWidth = image.getWidth(); int imageHeight = image.getHeight(); // Need an array (for RGB, with the size of original image) int rgb[] = new int[imageWidth * imageHeight]; // Get the RGB array of image into "rgb" image.getARGB(rgb, 0, imageWidth, 0, 0, imageWidth, imageHeight); // Call to rescaleArray() function and obtain rgb2 int rgb2[] = rescaleArray(rgb, imageWidth, imageHeight, width, height); // Create an image with that RGB array Bitmap temp2 = new Bitmap(width, height); temp2.setARGB(rgb2, 0, width, 0, 0, width, height); return temp2; } private static int[] rescaleArray(int[] ini, int x, int y, int x2, int y2) { int out[] = new int[x2 * y2]; for (int yy = 0; yy < y2; yy++) { int dy = yy * y / y2; for (int xx = 0; xx < x2; xx++) { int dx = xx * x / x2; out[(x2 * yy) + xx] = ini[(x * dy) + dx]; } } return out; } /** * Blackberry api 提供方法 * @param image * @param newWidth * @param newHeight * @return */ public static EncodedImage resizeImage(EncodedImage image, int newWidth, int newHeight) { int scaleFactorX = Fixed32.div(Fixed32.toFP(image.getWidth()), Fixed32.toFP(newWidth)); int scaleFactorY = Fixed32.div(Fixed32.toFP(image.getHeight()), Fixed32.toFP(newHeight)); return image.scaleImage32(scaleFactorX, scaleFactorY); } /** * Blackberry api 提供方法 (加强版) * @param image * @param targetWidth * @param targetHeight * @return */ public static EncodedImage scaleImageToSize(EncodedImage image, int targetWidth, int targetHeight) { try { if (targetWidth > 0 && targetHeight > 0) { int imageWidth = image.getWidth(); int imageHeight = image.getHeight(); float scaleX = ((float) imageWidth / (float) targetWidth) * 10000; float scaleY = ((float) imageHeight / (float) targetHeight) * 10000; int fixedX = Fixed32.tenThouToFP( (int) scaleX); int fixedY = Fixed32.tenThouToFP( (int) scaleY); EncodedImage retImage = image.scaleImage32(fixedX,fixedY); return retImage; } } catch(Exception e) { System.out.println("Exception in Utility : ScaleImageToSize() "+e.toString()); } return image; } private static EncodedImage changeBitmap2EncodedImage(Bitmap image, int width, int height){ return PNGEncodedImage.encode(image); } // 使用midp2.0的getRGB()函数 private static Bitmap ZoomImage(Image src, int desW, int desH) { Image desImg = null; int srcW = src.getWidth(); // 原始图像宽 int srcH = src.getHeight(); // 原始图像高 int[] srcBuf = new int[srcW * srcH]; // 原始图片像素信息缓存 src.getRGB(srcBuf, 0, srcW, 0, 0, srcW, srcH); // 计算插值表 int[] tabY = new int[desH]; int[] tabX = new int[desW]; int sb = 0; int db = 0; int tems = 0; int temd = 0; int distance = srcH > desH ? srcH : desH; for (int i = 0; i <= distance; i++) { /* 垂直方向 */ tabY[db] = sb; tems += srcH; temd += desH; if (tems > distance) { tems -= distance; sb++; } if (temd > distance) { temd -= distance; db++; } } sb = 0; db = 0; tems = 0; temd = 0; distance = srcW > desW ? srcW : desW; for (int i = 0; i <= distance; i++) { /* 水平方向 */ tabX[db] = (short) sb; tems += srcW; temd += desW; if (tems > distance) { tems -= distance; sb++; } if (temd > distance) { temd -= distance; db++; } } // 生成放大缩小后图形像素buf int[] desBuf = new int[desW * desH]; int dx = 0; int dy = 0; int sy = 0; int oldy = -1; for (int i = 0; i < desH; i++) { if (oldy == tabY[i]) { System.arraycopy(desBuf, dy - desW, desBuf, dy, desW); } else { dx = 0; for (int j = 0; j < desW; j++) { desBuf[dy + dx] = srcBuf[sy + tabX[j]]; dx++; } sy += (tabY[i] - oldy) * srcW; } oldy = tabY[i]; dy += desW; } // 生成图片 // desImg = Image.createRGBImage(desBuf, desW, desH, false); // return desImg; Bitmap bitmap = new Bitmap(desW, desH); bitmap.setARGB(desBuf, 0, desW, 0, 0, desW, desH); return bitmap; } /** * 双线性插值算法 * @param src 需要缩放的图片 * @param width_dest 缩放后的宽度 * @param height_dest 缩放后的高度 * @return */ private static Bitmap rizeImageByBiliNearInterpolation(Bitmap src, int width_dest, int height_dest) { int destW = width_dest; // 缩放后图片的宽度 int destH = height_dest; // 缩放图片的高度 int srcW = src.getWidth(); int srcH = src.getHeight(); int[] destPixels = new int[destW * destH]; // array to hold destination // Image src = Image.createImage("/image.png"); // create pixel arrays // int[] destPixels = new int[destW * destH]; // array to hold // destination int[] destRed = new int[destW * destH]; int[] destGreen = new int[destW * destH]; int[] destBlue = new int[destW * destH]; // pixels int[] srcPixels = new int[srcW * srcH]; // array with source's pixels int[] srcRed = new int[srcW * srcH]; int[] srcGreen = new int[srcW * srcH]; int[] srcBlue = new int[srcW * srcH]; src.getARGB(srcPixels, 0, srcW, 0, 0, srcW, srcH); try { for (int i = 0; i < srcPixels.length; i++) { srcBlue[i] = srcPixels[i] & 0x000000ff; srcGreen[i] = (srcPixels[i] >> 8) & 0x000000ff; srcRed[i] = (srcPixels[i] >> 16) & 0x000000ff; } // simple point smapled resizing // loop through the destination pixels, find the matching pixel on // the source and use that for (int destY = 0; destY < destH; ++destY) { for (int destX = 0; destX < destW; ++destX) { float srcX = ((float) destX * (float) srcW) / (float) destW; float srcY = ((float) destY * (float) srcH) / (float) destH; try { destRed[destX + destY * destW] = biliNearInterpolation(srcRed, srcW, srcH, srcX, srcY); destGreen[destX + destY * destW] = biliNearInterpolation( srcGreen, srcW, srcH, srcX, srcY); destBlue[destX + destY * destW] = biliNearInterpolation( srcBlue, srcW, srcH, srcX, srcY); int value = 0xff000000; value |= destBlue[destX + destY * destW]; value |= (destGreen[destX + destY * destW] << 8); value |= (destRed[destX + destY * destW] << 16); destPixels[destX + destY * destW] = value; } catch (Exception e) { e.printStackTrace(); } } } } catch (Exception e) { e.printStackTrace(); } Bitmap tmp = new Bitmap(destW, destH); tmp.setARGB(destPixels, 0, destW, 0, 0, destW, destH); return tmp; } /** * 双线性插值算法 * @param imageData * @param width * @param heigth * @param x * @param y * @return */ private static int biliNearInterpolation(int[] imageData, int width, int heigth, float x, float y) { // 四个最临近象素的坐标(i1, j1), (i2, j1), (i1, j2), (i2, j2) int i1, i2; int j1, j2; int f1, f2, f3, f4; // 四个最临近象素值 int f12, f34; // 二个插值中间值 f1 = f2 = f3 = f4 = 0; // 定义一个值,当象素坐标相差小于改值时认为坐标相同 int EXP = 0; // 计算四个最临近象素的坐标 i1 = (int) x; i2 = i1 + 1; j1 = (int) y; j2 = j1 + 1; // 根据不同情况分别处理 if ((x < 0) || (x > width - 1) || (y < 0) || (y > heigth - 1)) { return 0x00ffffff; // 要计算的点不在源图范围内,直接返回255。 } else { if (Math.abs(x - width + 1) <= EXP) { // 要计算的点在图像右边缘上 if (Math.abs(y - heigth + 1) <= EXP) { // 要计算的点正好是图像最右下角那一个象素,直接返回该点象素值 f1 = (int) imageData[width * j1 + i1]; return (int) f1; } else { // 在图像右边缘上且不是最后一点,直接一次插值即可 f1 = (int) imageData[width * j1 + i1]; f3 = (int) imageData[width * j1 + i2]; // 返回插值结果 return (int) (f1 + (y - j1) * (f3 - f1)); } } else if (Math.abs(y - heigth + 1) <= EXP) { // 要计算的点在图像下边缘上且不是最后一点,直接一次插值即可 f1 = (int) imageData[width * j1 + i1]; f2 = (int) imageData[width * j2 + i1]; // 返回插值结果 return (int) (f1 + (x - i1) * (f2 - f1)); } else { // 计算四个最临近象素值 f1 = imageData[width * j1 + i1]; f2 = imageData[width * j1 + i2]; f3 = imageData[width * j2 + i1]; f4 = imageData[width * j2 + i2]; // 插值1 f12 = (int) (f1 + (x - i1) * (f2 - f1)); // 插值2 f34 = (int) ((f3 + (x - i1) * (f4 - f3))); // 插值3 return (int) (f12 + (y - j1) * (f34 - f12)); } } } }


    最新回复(0)