具有任意长宽比的 android Gallery

发布于 2024-11-01 19:21:31 字数 1023 浏览 1 评论 0原文

我希望有一个 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;
}

i wish to have an android gallery that will host images of varying aspect ratios. what i'd like is something like CENTER_CROP for the images in the gallery. however, when i set the image scale type to this, the images overrun the gallery image border.

of course, FIT_XY results in squished / flattened images. CENTER results in horizontal or vertical black space inside the gallery image border.

any ideas how to accomplish this? every example i can find uses FIT_XY with fixed size images. i suppose i could crop the images myself but i'd rather not.

@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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你如我软肋 2024-11-08 19:21:31

我遇到了和你一样的问题,查看 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,你还需要使用矩阵缩放。所以我有兴趣了解任何可能的替代方案。

I had the same problem as you and looking at ScaleType documentation I found it could be done using ScaleType.MATRIX, for example:

    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);

This solution complicates things a little bit too much though. If you want to scroll and zoom the ImageView you need to use matrix scaling as well. So I'd be interested in knowing any possible alternative.

千纸鹤带着心事 2024-11-08 19:21:31

对于此类任务,我使用这个简单的类。它适合正确缩放图像的高度或宽度(这取决于哪个尺寸较小)。执行此操作后,它将图像置于 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);
    }
}

For this kind of tasks I use this simple class. It fits height or width scaling the image properly (it depends on which is the smaller dimension) . After this operation it centers the image in the ImageView bounds.

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);
    }
}
请恋爱 2024-11-08 19:21:31

我最终只是自己将位图修剪成正方形,因为,

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);
}

I ended up just trimming the bitmap to a square myself, as,

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文