Android:高质量图像大小/缩放
我需要在不损失质量的情况下缩小来自网络流的图像 我知道这个解决方案,但它太粗糙了-Android:高质量图像大小/缩放,android,algorithm,image,scaling,Android,Algorithm,Image,Scaling,我需要在不损失质量的情况下缩小来自网络流的图像 我知道这个解决方案,但它太粗糙了-inSampleSize是一个整数,不允许对结果维度进行更精细的控制。也就是说,我需要将图像缩放到特定的h/w维度(并保持纵横比) 我不介意在我的代码中使用DIY双三次/lancoz算法,但我找不到任何可以在Android上运行的示例,因为它们都依赖于Java2D(JavaSE) 编辑: 我附上了一个快速来源。原版是720x402高清屏幕截图。请忽略前2个缩略图。顶部的大图像由android自动调整大小(作为布局的
inSampleSize
是一个整数,不允许对结果维度进行更精细的控制。也就是说,我需要将图像缩放到特定的h/w维度(并保持纵横比)
我不介意在我的代码中使用DIY双三次/lancoz算法,但我找不到任何可以在Android上运行的示例,因为它们都依赖于Java2D(JavaSE)
编辑:
我附上了一个快速来源。原版是720x402高清屏幕截图。请忽略前2个缩略图。顶部的大图像由android自动调整大小(作为布局的一部分)至130x72左右。它又好又脆。底部图像使用API调整大小,并且存在严重的伪影
我也尝试过使用BitmapFactory,正如我前面所说,它有两个问题——无法缩放到精确的大小,缩放后的图像模糊
关于如何修复工件有什么想法吗
谢谢,S.O
package qp.test;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.os.Bundle;
import android.widget.ImageView;
public class imgview extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Bitmap original = BitmapFactory.decodeResource(getResources(), R.drawable.a000001570402);
Bitmap resized = getResizedBitmap(original, 130);
//Bitmap resized = getResizedBitmap2(original, 0.3f);
System.err.println(resized.getWidth() + "x" + resized.getHeight());
ImageView image = (ImageView) findViewById(R.id.ImageViewFullManual);
image.setImageBitmap(resized);
}
private Bitmap getResizedBitmap(Bitmap bm, int newWidth) {
int width = bm.getWidth();
int height = bm.getHeight();
float aspect = (float)width / height;
float scaleWidth = newWidth;
float scaleHeight = scaleWidth / aspect; // yeah!
// create a matrix for the manipulation
Matrix matrix = new Matrix();
// resize the bit map
matrix.postScale(scaleWidth / width, scaleHeight / height);
// recreate the new Bitmap
Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, true);
bm.recycle();
return resizedBitmap;
}
private Bitmap getResizedBitmap2(Bitmap bm, float scale) {
/* float aspect = bm.getWidth() / bm.getHeight();
int scaleWidth = (int) (bm.getWidth() * scale);
int scaleHeight = (int) (bm.getHeight() * scale);
*/
// original image is 720x402 and SampleSize=4 produces 180x102, which is
// still too large
BitmapFactory.Options bfo = new BitmapFactory.Options();
bfo.inSampleSize = 4;
return BitmapFactory.decodeResource(getResources(), R.drawable.a000001570402, bfo);
}
}
布局呢
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<!-- <TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="hullo" android:background="#00ff00"
/>
-->
<ImageView android:id="@+id/ImageViewThumbAuto"
android:layout_width="130dip" android:layout_height="72dip"
android:src="@drawable/a000001570402" />
<ImageView android:id="@+id/ImageViewThumbManual"
android:layout_width="130dip" android:layout_height="72dip"
android:src="@drawable/a000001570402"
android:layout_toRightOf="@id/ImageViewThumbAuto"
/>
<ImageView android:id="@+id/ImageViewFullAuto" android:layout_width="300dip"
android:layout_height="169dip"
android:scaleType="fitXY"
android:src="@drawable/a000001570402"
android:layout_below="@id/ImageViewThumbAuto"
/>
<ImageView android:id="@+id/ImageViewFullManual" android:layout_width="300dip"
android:layout_height="169dip"
android:scaleType="fitXY"
android:src="@drawable/a000001570402"
android:layout_below="@id/ImageViewFullAuto"
/>
</RelativeLayout>
顶部的大图像仅通过布局缩小到450px,因此没有任何瑕疵 底部大图像的伪影是通过将其缩小到130px宽,然后再根据布局将其放大到450px左右而产生的。因此,这些工件是通过缩放来制作的。试一试
Bitmap resized = getResizedBitmap(original, 450);
在你的代码中,它应该是好的。但是,您也需要根据手机的实际屏幕宽度进行调整。您可以使用
BitmapFactory.Options
和BitmapFactory.decode
功能,在目标密度中使用
和
示例:您有1600x1200大小的图像,并希望将其大小调整为640x480
然后
'inDensity'=5
和'inTargetDensity'=2
(1600x2等于640x5)。希望能有所帮助。简单地说,好的降尺度算法(不是最近邻算法)包括两个步骤:
以下是SonyMobile scale utils的源代码:我不认为顶部图像实际上是130像素宽。是128像素宽…查看有关解码图像的信息。嗨!面对同样的问题,你们找到解决方案了吗?不幸的是,这会导致最近邻缩小。正如我发现的,为了保持双三次降尺度,只允许更改inSampleSize。