Android gallery with arbitrary proportions

I want to have an Android gallery that will host images with different proportions. what i need is something like CENTER_CROP for images in the gallery. however, when I set the type of image scale for this, the images exceed the border of the gallery image.

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

any ideas how to do this? every example i can find uses FIT_XY with fixed size images. I suppose I cropped the images myself, but I would prefer not to.

@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; } 
+4
source share
3 answers

since no one else answered, I ended up just cropping the bitmap into a square like,

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

I had the same problem as you, and looking at the ScaleType documentation, I found that this can 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 decision complicates the situation a bit. If you want to scroll and scale the ImageView, you also need to use matrix scaling. Therefore, I would be interested to know any possible alternative.

0
source

For such tasks, I use this simple class. It matches the height or width, scaling the image properly (it depends on which size is smaller). After this operation, it centers the image within the 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
source

All Articles