Android-галерея с произвольными пропорциями - PullRequest
4 голосов
/ 18 апреля 2011

Я хочу иметь галерею 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 голосов
/ 03 ноября 2011

У меня была та же проблема, что и у вас, и, глядя на документацию 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, вам также необходимо использовать матричное масштабирование.Поэтому мне было бы интересно узнать любую возможную альтернативу.

0 голосов
/ 28 августа 2015

Для такого рода задач я использую этот простой класс. Это соответствует высоте или ширине, масштабируя изображение должным образом (это зависит от того, какой размер меньше). После этой операции он центрирует изображение в границах 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);
    }
}
0 голосов
/ 20 апреля 2011

, так как никто не ответил, я в итоге просто урезал растровое изображение до квадрата, как,

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