5 Stimmen

Android Galerie mit beliebigen Seitenverhältnissen

Ich möchte eine Android-Galerie, die Bilder mit unterschiedlichen Seitenverhältnissen hosten wird. Was ich möchte, ist so etwas wie CENTER_CROP für die Bilder in der Galerie. jedoch, wenn ich den Bildskalierungstyp auf diese eingestellt, die Bilder über die Galerie Bild Grenze.

FIT_XY führt natürlich zu gequetschten / abgeflachten Bildern. CENTER führt zu horizontalem oder vertikalem schwarzem Raum innerhalb des Bildrandes der Galerie.

alle Ideen, wie dies zu erreichen? jedes Beispiel, das ich finden kann, verwendet FIT_XY mit festen Größe Bilder. ich nehme an, ich könnte die Bilder selbst beschneiden, aber ich würde lieber nicht.

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

0voto

Jeffrey Blattman Punkte 21673

Am Ende habe ich die Bitmap einfach selbst auf ein Quadrat zugeschnitten, denn,

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

0voto

Narcís Calvet Punkte 7151

Ich hatte das gleiche Problem wie Sie und habe in der ScaleType-Dokumentation nachgeschaut, dass man es zum Beispiel mit ScaleType.MATRIX machen kann:

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

Diese Lösung verkompliziert die Dinge allerdings ein wenig zu sehr. Wenn man in der ImageView scrollen und zoomen will, muss man auch die Matrixskalierung verwenden. Daher wäre ich an einer möglichen Alternative interessiert.

0voto

carlol Punkte 2170

Für diese Art von Aufgaben verwende ich diese einfache Klasse. Sie passt sich der Höhe oder Breite an und skaliert das Bild entsprechend (je nachdem, welches die kleinere Dimension ist). Nach dieser Operation zentriert sie das Bild in den Grenzen von 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);
    }
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X