在android上转换原始位图

在android上转换原始位图,android,Android,所以,我使用这个库将“MultiTouchListener”功能添加到我的ImageView中。基本上,我允许用户使用旋转、缩放和平移来根据自己的需要修改照片。现在唯一的问题是如何保存它。我是这样做的: Bitmap bitmap = Bitmap.createBitmap(imageContainer.getWidth(), imageContainer.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Can

所以,我使用这个库将“MultiTouchListener”功能添加到我的ImageView中。基本上,我允许用户使用旋转、缩放和平移来根据自己的需要修改照片。现在唯一的问题是如何保存它。我是这样做的:

    Bitmap bitmap = Bitmap.createBitmap(imageContainer.getWidth(), imageContainer.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    canvas.drawColor(Color.WHITE);
    imageContainer.draw(canvas);
它可以工作,但图像不够大——它和手机上的视图一样大,所以取决于屏幕分辨率。我想在给定的位图上以全尺寸“应用”这些变换。我希望转换后的图像看起来像在屏幕上(所以它需要从屏幕上裁剪出所有内容)

我尝试了以下方法:

    Bitmap newBitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(newBitmap);
    canvas.drawColor(Color.WHITE);
    Paint paint = new Paint();
    paint.setAntiAlias(true);
    canvas.drawBitmap(image, imageView.getMatrix(), paint);
但看起来并不像预期的那样

用户屏幕:

并输出图像(不剪切,因为我不想剪切哪一侧):


我怎样才能解决这个问题?有什么解决办法吗?

这里有一种方法可以做到这一点,绝对不是十全十美的,但应该给你一个良好的开端:

在这种情况下,
container
指的是包含转换后的
ImageView
、屏幕截图上的手机壳和
src
原始源位图的视图

  • 首先,您需要计算输出位图的所需宽度和高度,即在保持容器比率的同时使图像适合位图的大小:

    float containerWidth = containerView.getWidth();
    float containerHeight = containerView.getHeight();
    
    float srcWidth = src.getWidth();
    float srcHeight = src.getHeight();
    
    float containerRatio = containerWidth / containerHeight;
    float srcRatio = srcWidth / srcHeight;
    
    float outputWidth, outputHeight;
    
    if(srcRatio > containerRatio) { //fits in width
            outputWidth = srcWidth;
            outputHeight = srcWidth / containerRatio;
    }
    else if(srcRatio < containerRatio) { //fits in height
            outputHeight = srcHeight;
            outputWidth = srcHeight * containerRatio;
    }
    else {
        outputWidth = srcWidth;
        outputHeight = srcHeight;
    }
    
  • 按照正确的大小(outputWidth、outputHeight)和矩阵(outputMatrix)绘制输出位图

警告

您应该注意内存分配,这段代码将导致分配一些海量位图,您应该实现某种符合您需要的限制。(也在后台进行分配和绘图)


您可能需要进行一些调整,具体取决于您将图像放在首位的位置。

谢谢您的详细回答!我尝试了你的方法,但不知为什么输出位图不在正确的位置。查看我的代码。您可以轻松地在我的旧方法和您的方法之间切换以查看输出。如果没有布局和资产文件,这就不相关了,下面是答案中代码的一个更完整、更易于获取的运行版本:。正如我在回答中所说,您可能需要根据您的布局进行一些调整……是的,您的代码工作得非常好。我发现了这个问题——这是imageView的设置大小——它使它看起来不同。我刚刚删除了那条线。现在,我正在努力完成最后一步——使初始图像看起来像方面填充(初始加载照片后没有空白)。在您的示例中,我尝试了android:scaleType=“centerCrop”,但它没有任何作用。正如我所说,代码需要根据您将图像放在首位的方式进行一些调整(与
fitStart
一起使用),可能是因为
ImageView#getMatrix()
只包含视图的转换,不是视图内部的可绘制视图。稍后我会给你发一些代码。也不要错过
adjustViewBounds=“true”
。是的,我添加了adjustViewBounds。正在查找您的代码:)
float containerToOutputRatioWidth = outputWidth / containerWidth;
float containerToOutputRatioHeight = outputHeight / containerHeight;

float[] values = new float[9];
transformedImageView.getMatrix().getValues(values);
values[2] = values[2] * containerToOutputRatioWidth;
values[5] = values[5] * containerToOutputRatioHeight;
Matrix outputMatrix = new Matrix();
outputMatrix.setValues(values);
Bitmap newBitmap = Bitmap.createBitmap(Math.round(outputWidth), Math.round(outputHeight), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.WHITE);
Paint paint = new Paint();
paint.setAntiAlias(true);
canvas.drawBitmap(src, outputMatrix, paint);