在Android中调整位图大小会导致黑色边框

时间:2017-09-30 15:06:24

标签: android android-bitmap

我正在尝试在Android中调整位图大小,但结果始终为黑色边框。

enter image description here

我曾被告知这是因为我没有使用确切的宽度和高度。 createScaledBitmap方法只允许使用int。我为此尝试了解决方案/片段,但即使将浮点数转换为整数,问题仍然存在,我发现没有区别。

我保持宽高比。

有没有人有一个有效的例子?

代码:

                            int dstWidth = (int)(srcWidth*0.15f);

                            BitmapFactory.Options options = new BitmapFactory.Options();
                            options.inScaled = false;
                            Bitmap newBitmap = getScaledDownBitmap(orientedBitmap, dstWidth, false);

它的调用方法:

  public static Bitmap getScaledDownBitmap(Bitmap bitmap, int threshold, boolean isNecessaryToKeepOrig){
    int width = bitmap.getWidth();
    int height = bitmap.getHeight();
    int newWidth = width;
    int newHeight = height;

    if(width > height && width > threshold){
        newWidth = threshold;
        newHeight = (int)(height * (float)newWidth/width);
    }

    if(width > height && width <= threshold){
        //the bitmap is already smaller than our required dimension, no need to resize it
        return bitmap;
    }

    if(width < height && height > threshold){
        newHeight = threshold;
        newWidth = (int)(width * (float)newHeight/height);
    }

    if(width < height && height <= threshold){
        //the bitmap is already smaller than our required dimension, no need to resize it
        return bitmap;
    }

    if(width == height && width > threshold){
        newWidth = threshold;
        newHeight = newWidth;
    }

    if(width == height && width <= threshold){
        //the bitmap is already smaller than our required dimension, no need to resize it
        return bitmap;
    }

    return getResizedBitmap(bitmap, newWidth, newHeight, isNecessaryToKeepOrig);
}

您也知道,createScaledBitmap也会发生同样的事情。我尝试了多张图片。

代码的样子,使用Marzieh Heidari的代码(没有解决问题)

                            File imagefile = new File(filePath);
                        FileInputStream fis = null;
                        try{
                            fis = new FileInputStream(imagefile);
                        }catch(FileNotFoundException e){
                            e.printStackTrace();
                        }

                        Bitmap bm = BitmapFactory.decodeStream(fis);
                        Bitmap orientedBitmap = ExifUtil.rotateBitmap(filePath, bm);

                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        if(orientedBitmap.getHeight() >= 600 && orientedBitmap.getWidth() >= 600) {
                            int srcWidth = orientedBitmap.getWidth();
                            int srcHeight = orientedBitmap.getHeight();
                            int dstWidth = (int)(srcWidth*0.15f);
                            int dstHeight = (int)(srcHeight*0.15f);

                            BitmapFactory.Options options = new BitmapFactory.Options();
                            options.inScaled = false;
                            Bitmap newBitmap = createScaledBitmap(orientedBitmap, dstWidth, dstHeight, ScalingLogic.CROP);
                            newBitmap.compress(Bitmap.CompressFormat.JPEG,60,baos);
                            byte[] b = baos.toByteArray();
                            encImage = Base64.encodeToString(b, Base64.DEFAULT);
                        } else {
                            orientedBitmap.compress(Bitmap.CompressFormat.JPEG, 60, baos);
                            byte[] b = baos.toByteArray();
                            encImage = Base64.encodeToString(b, Base64.DEFAULT);
                        }

从那里我基本上将base64发布到PHP

$base = $_POST['base'];
$imageData = base64_decode($base);
$source = imagecreatefromstring($imageData);

$imageName = 'avatars/1.jpeg';
$imageSave = imagejpeg($imageName,100);
imagedestroy($source);

XML

    <RelativeLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@drawable/image_border_blue">
<ImageView
    android:id="@+id/imageView"
    android:layout_width="58dp"
    android:layout_height="58dp"
    android:clickable="true"
    android:scaleType="centerCrop"
    android:onClick="StartImage"
    android:src="@drawable/user_male_icon" />
</RelativeLayout>

user_male_icon只是默认设置,使用Ion:

加载图像
        Ion.with(nav_image)
            .placeholder(R.drawable.user_male_icon)
            .load(Settings.WEBSITE_ADDR + "/-------/avatars/1.jpeg");

2 个答案:

答案 0 :(得分:0)

这是我用于缩放位图的方法。希望它有所帮助

 /**
 * Utility function for creating a scaled version of an existing bitmap
 *
 * @param unscaledBitmap Bitmap to scale
 * @param dstWidth       Wanted width of destination bitmap
 * @param dstHeight      Wanted height of destination bitmap
 * @param scalingLogic   Logic to use to avoid image stretching
 * @return New scaled bitmap object
 */
public static Bitmap createScaledBitmap(Bitmap unscaledBitmap, int dstWidth, int dstHeight,
                                        ScalingLogic scalingLogic) {
    Rect srcRect = calculateSrcRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
            dstWidth, dstHeight, scalingLogic);
    Rect dstRect = calculateDstRect(unscaledBitmap.getWidth(), unscaledBitmap.getHeight(),
            dstWidth, dstHeight, scalingLogic);
    Bitmap scaledBitmap = Bitmap.createBitmap(dstRect.width(), dstRect.height(),
            Config.ARGB_8888);
    Canvas canvas = new Canvas(scaledBitmap);
    canvas.drawBitmap(unscaledBitmap, srcRect, dstRect, new Paint(Paint.FILTER_BITMAP_FLAG));

    return scaledBitmap;
}

/**
 * Calculates source rectangle for scaling bitmap
 *
 * @param srcWidth     Width of source image
 * @param srcHeight    Height of source image
 * @param dstWidth     Width of destination area
 * @param dstHeight    Height of destination area
 * @param scalingLogic Logic to use to avoid image stretching
 * @return Optimal source rectangle
 */


   private static Rect calculateSrcRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
                                         ScalingLogic scalingLogic) {
        if (scalingLogic == ScalingLogic.CROP) {
            float srcAspect = (float) srcWidth / (float) srcHeight;
            float dstAspect = (float) dstWidth / (float) dstHeight;

            if (srcAspect > dstAspect) {
                int srcRectWidth = (int) (srcHeight * dstAspect);
                int srcRectLeft = (srcWidth - srcRectWidth) / 2;
                return new Rect(srcRectLeft, 0, srcRectLeft + srcRectWidth, srcHeight);
            } else {
                int srcRectHeight = (int) (srcWidth / dstAspect);
                int scrRectTop = (srcHeight - srcRectHeight) / 2;
                return new Rect(0, scrRectTop, srcWidth, scrRectTop + srcRectHeight);
            }
        } else {
            return new Rect(0, 0, srcWidth, srcHeight);
        }
    }

    /**
     * Calculates destination rectangle for scaling bitmap
     *
     * @param srcWidth     Width of source image
     * @param srcHeight    Height of source image
     * @param dstWidth     Width of destination area
     * @param dstHeight    Height of destination area
     * @param scalingLogic Logic to use to avoid image stretching
     * @return Optimal destination rectangle
     */
    private static Rect calculateDstRect(int srcWidth, int srcHeight, int dstWidth, int dstHeight,
                                         ScalingLogic scalingLogic) {
        if (scalingLogic == ScalingLogic.FIT) {
            float srcAspect = (float) srcWidth / (float) srcHeight;
            float dstAspect = (float) dstWidth / (float) dstHeight;

            if (srcAspect > dstAspect) {
                return new Rect(0, 0, dstWidth, (int) (dstWidth / srcAspect));
            } else {
                return new Rect(0, 0, (int) (dstHeight * srcAspect), dstHeight);
            }
        } else {
            return new Rect(0, 0, dstWidth, dstHeight);
        }
    }
 /**
     * ScalingLogic defines how scaling should be carried out if source and
     * destination image has different aspect ratio.
     * <p>
     * CROP: Scales the image the minimum amount while making sure that at least
     * one of the two dimensions fit inside the requested destination area.
     * Parts of the source image will be cropped to realize this.
     * <p>
     * FIT: Scales the image the minimum amount while making sure both
     * dimensions fit inside the requested destination area. The resulting
     * destination dimensions might be adjusted to a smaller size than
     * requested.
     */
    public enum ScalingLogic {
        CROP, FIT
    }

更新: 你提到你需要一些东西来裁剪图像。我希望这个帮助

Bitmap croppedBmp = Bitmap.createBitmap(originalBmp, rectanglePositionX, rectanglePositionY, rectangleWidth, rectangleHeight);

rectanglePositionXrectanglePositionY必须是边框宽度,rectangleWidth shuold是bitmep width - borderWidth,最后rectangleHeight应该是bitmep height-borderWidth

答案 1 :(得分:0)

这是一个奇怪的案例。请尝试以下方法之一:

  • 使用scaleType fitCenter
  • 关闭硬件加速
  • 在其他设备中测试代码。