具有任意宽高比的android Gallery

时间:2011-04-18 18:05:54

标签: android image gallery

我希望有一个Android图库,可以托管不同宽高比的图像。对于图库中的图像,我想要的是CENTER_CROP。但是,当我将图像比例类型设置为此时,图像会超出图库图像边框。

当然,FIT_XY导致压缩/展平图像。 CENTER会在图库边框内产生水平或垂直黑色空间。

任何想法如何实现这一目标?我能找到的每个例子都使用FIT_XY和固定大小的图像。我想我可以自己裁剪图像,但我宁愿不这样做。

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ImageView iv = (ImageView) convertView;
    if (iv == null) {
        iv = new ImageView(context);
        iv.setScaleType(ImageView.ScaleType.FIT_XY);
        iv.setBackgroundResource(galleryItemBackground);
        iv.setLayoutParams(new Gallery.LayoutParams(200, 200));
    }

    InputStream is;
    try {
        is = getInputStream(position);
    } catch (IOException ioe) {
        // TODO?
        throw new RuntimeException(ioe);
    }
    Bitmap bm = BitmapFactory.decodeStream(is);
    iv.setImageBitmap(bm);



    /*
     * if (bitmaps[position] != null) { bitmaps[position].recycle();
     * bitmaps[position] = null; } bitmaps[position] = bm;
     */

    return iv;
}

3 个答案:

答案 0 :(得分:0)

因为没有其他人回答,我最终只是将位图修剪为正方形,如,

Bitmap bm = BitmapFactory.decodeStream(is);

// make it square

int w = bm.getWidth();
int h = bm.getHeight();
if (w > h) {
    // trim width
    bm = Bitmap.createBitmap(bm, (w - h) / 2, 0, h, h);
} else {
    bm = Bitmap.createBitmap(bm, 0, (h - w) / 2, w, w);
}

答案 1 :(得分:0)

我遇到了和你一样的问题并且查看了ScaleType文档我发现它可以使用ScaleType.MATRIX来完成,例如:

    int w = 1000;
    int h = 1000;

    Paint p = new Paint();
    p.setShader(new LinearGradient(0, 0, w, h, Color.BLACK, Color.RED, Shader.TileMode.CLAMP));

    Bitmap bmp = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
    Canvas g = new Canvas(bmp);     
    g.drawRect(new Rect(0, 0, w, h), p);

    ImageView i3 = new ImageView(context);
    i3.setImageBitmap(bmp);
    i3.setScaleType(ScaleType.MATRIX);

    int viewWidth = 300;
    int viewHeight = 300;

    Matrix matrix = new Matrix();
    matrix.postScale(bmp.getWidth() / viewWidth, bmp.getHeight() / viewHeight, bmp.getWidth() / 2, bmp.getHeight() / 2);
    i3.setImageMatrix(matrix);

    LayoutParams lp2 = new LayoutParams(viewWidth, viewHeight);
    lp2.leftMargin = 100;
    lp2.topMargin = 400;
    lp2.gravity = 0;

    this.addView(i3, lp2);

这个解决方案虽然有点太复杂了。如果要滚动和缩放ImageView,还需要使用矩阵缩放。所以我有兴趣了解任何可能的替代方案。

答案 2 :(得分:0)

对于这类任务,我使用这个简单的类。它适合高度或宽度适当缩放图像(取决于哪个是较小的尺寸)。在此操作之后,它将图像置于ImageView边界中。

public class FixedCenterCrop extends ImageView {


    public FixedCenterCrop(Context context) {
        super(context);
        setScaleType(ScaleType.MATRIX);
    }

    public FixedCenterCrop(Context context, AttributeSet attrs) {
        super(context, attrs);
        setScaleType(ScaleType.MATRIX);
    }

    public FixedCenterCrop(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        setScaleType(ScaleType.MATRIX);
    }


    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        recomputeImgMatrix();
    }

    @Override
    protected boolean setFrame(int l, int t, int r, int b) {
        recomputeImgMatrix();
        return super.setFrame(l, t, r, b);
    }

    private void recomputeImgMatrix() {
        final Matrix matrix = getImageMatrix();

        float scale;
        final int viewWidth = getWidth() - getPaddingLeft() - getPaddingRight();
        final int viewHeight = getHeight() - getPaddingTop() - getPaddingBottom();
        final int drawableWidth = getDrawable().getIntrinsicWidth();
        final int drawableHeight = getDrawable().getIntrinsicHeight();

        if (drawableWidth * viewHeight > drawableHeight * viewWidth) {
            scale = (float) viewHeight / (float) drawableHeight;
        } else {
            scale = (float) viewWidth / (float) drawableWidth;
        }

        matrix.setScale(scale, scale);
        matrix.postTranslate((viewWidth - drawableWidth * scale) / 2, (viewHeight - drawableHeight*scale)/2);
        setImageMatrix(matrix);
    }
}