From cf4604e0d84278e91f1e87f028cb3ecb54a3911e Mon Sep 17 00:00:00 2001 From: Grishka Date: Fri, 24 Mar 2023 01:33:33 +0300 Subject: [PATCH] More media layout optimizations --- .../android/ui/PhotoLayoutHelper.java | 139 +++++++++--------- .../android/ui/views/MediaGridLayout.java | 8 +- 2 files changed, 75 insertions(+), 72 deletions(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/PhotoLayoutHelper.java b/mastodon/src/main/java/org/joinmastodon/android/ui/PhotoLayoutHelper.java index e798fa7d..ba173466 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/PhotoLayoutHelper.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/PhotoLayoutHelper.java @@ -14,22 +14,23 @@ public class PhotoLayoutHelper{ public static final int MAX_WIDTH=1000; public static final int MAX_HEIGHT=1777; // 9:16 public static final int MIN_HEIGHT=563; + public static final float GAP=1.5f; @NonNull public static TiledLayoutResult processThumbs(List thumbs){ - int _maxW=MAX_WIDTH; - int _maxH=MAX_HEIGHT; + float maxRatio=MAX_WIDTH/(float)MAX_HEIGHT; TiledLayoutResult result=new TiledLayoutResult(); if(thumbs.size()==1){ Attachment att=thumbs.get(0); result.rowSizes=result.columnSizes=new int[]{1}; - if(att.getWidth()>att.getHeight()){ - result.width=_maxW; - result.height=Math.max(MIN_HEIGHT, Math.round(att.getHeight()/(float)att.getWidth()*_maxW)); + float ratio=att.getWidth()/(float) att.getHeight(); + if(ratio>maxRatio){ + result.width=MAX_WIDTH; + result.height=Math.max(MIN_HEIGHT, Math.round(att.getHeight()/(float)att.getWidth()*MAX_WIDTH)); }else{ - result.height=_maxH; - result.width=Math.round(att.getWidth()/(float)att.getHeight()*_maxH); + result.height=MAX_HEIGHT; + result.width=MAX_WIDTH;//Math.round(att.getWidth()/(float)att.getHeight()*MAX_HEIGHT); } result.tiles=new TiledLayoutResult.Tile[]{new TiledLayoutResult.Tile(1, 1, result.width, result.height, 0, 0)}; return result; @@ -38,7 +39,7 @@ public class PhotoLayoutHelper{ } String orients=""; - ArrayList ratios=new ArrayList(); + ArrayList ratios=new ArrayList<>(); int cnt=thumbs.size(); @@ -51,44 +52,38 @@ public class PhotoLayoutHelper{ float avgRatio=!ratios.isEmpty() ? sum(ratios)/ratios.size() : 1.0f; - float maxW, maxH, marginW=0, marginH=0; - maxW=_maxW; - maxH=_maxH; - - float maxRatio=maxW/maxH; - if(cnt==2){ if(orients.equals("ww") && avgRatio>1.4*maxRatio && (ratios.get(1)-ratios.get(0))<0.2){ // two wide photos, one above the other - float h=Math.max(Math.min(maxW/ratios.get(0), Math.min(maxW/ratios.get(1), (maxH-marginH)/2.0f)), MIN_HEIGHT/2f); + float h=Math.max(Math.min(MAX_WIDTH/ratios.get(0), Math.min(MAX_WIDTH/ratios.get(1), (MAX_HEIGHT-GAP)/2.0f)), MIN_HEIGHT/2f); - result.width=Math.round(maxW); - result.height=Math.round(h*2+marginH); + result.width=MAX_WIDTH; + result.height=Math.round(h*2+GAP); result.columnSizes=new int[]{result.width}; result.rowSizes=new int[]{Math.round(h), Math.round(h)}; result.tiles=new TiledLayoutResult.Tile[]{ - new TiledLayoutResult.Tile(1, 1, maxW, h, 0, 0), - new TiledLayoutResult.Tile(1, 1, maxW, h, 0, 1) + new TiledLayoutResult.Tile(1, 1, MAX_WIDTH, h, 0, 0), + new TiledLayoutResult.Tile(1, 1, MAX_WIDTH, h, 0, 1) }; }else if(orients.equals("ww") || orients.equals("qq")){ // next to each other, same ratio - float w=((maxW-marginW)/2); - float h=Math.max(Math.min(w/ratios.get(0), Math.min(w/ratios.get(1), maxH)), MIN_HEIGHT); + float w=((MAX_WIDTH-GAP)/2); + float h=Math.max(Math.min(w/ratios.get(0), Math.min(w/ratios.get(1), MAX_HEIGHT)), MIN_HEIGHT); - result.width=Math.round(maxW); + result.width=MAX_WIDTH; result.height=Math.round(h); - result.columnSizes=new int[]{Math.round(w), _maxW-Math.round(w)}; + result.columnSizes=new int[]{Math.round(w), MAX_WIDTH-Math.round(w)}; result.rowSizes=new int[]{Math.round(h)}; result.tiles=new TiledLayoutResult.Tile[]{ new TiledLayoutResult.Tile(1, 1, w, h, 0, 0), new TiledLayoutResult.Tile(1, 1, w, h, 1, 0) }; }else{ // next to each other, different ratios - float w0=((maxW-marginW)/ratios.get(1)/(1/ratios.get(0)+1/ratios.get(1))); - float w1=(maxW-w0-marginW); - float h=Math.max(Math.min(maxH, Math.min(w0/ratios.get(0), w1/ratios.get(1))), MIN_HEIGHT); + float w0=((MAX_WIDTH-GAP)/ratios.get(1)/(1/ratios.get(0)+1/ratios.get(1))); + float w1=(MAX_WIDTH-w0-GAP); + float h=Math.max(Math.min(MAX_HEIGHT, Math.min(w0/ratios.get(0), w1/ratios.get(1))), MIN_HEIGHT); result.columnSizes=new int[]{Math.round(w0), Math.round(w1)}; result.rowSizes=new int[]{Math.round(h)}; - result.width=Math.round(w0+w1+marginW); + result.width=Math.round(w0+w1+GAP); result.height=Math.round(h); result.tiles=new TiledLayoutResult.Tile[]{ new TiledLayoutResult.Tile(1, 1, w0, h, 0, 0), @@ -97,74 +92,76 @@ public class PhotoLayoutHelper{ } }else if(cnt==3){ if((ratios.get(0) > 1.2 * maxRatio || avgRatio > 1.5 * maxRatio) || orients.equals("www")){ // 2nd and 3rd photos are on the next line - float hCover=Math.min(maxW/ratios.get(0), (maxH-marginH)*0.66f); - float w2=((maxW-marginW)/2); - float h=Math.min(maxH-hCover-marginH, Math.min(w2/ratios.get(1), w2/ratios.get(2))); + float hCover=Math.min(MAX_WIDTH/ratios.get(0), (MAX_HEIGHT-GAP)*0.66f); + float w2=((MAX_WIDTH-GAP)/2); + float h=Math.min(MAX_HEIGHT-hCover-GAP, Math.min(w2/ratios.get(1), w2/ratios.get(2))); if(hCover+h 1.2 * maxRatio || avgRatio > 1.5 * maxRatio) || orients.equals("wwww")){ // 2nd, 3rd and 4th photos are on the next line - float hCover=Math.min(maxW/ratios.get(0), (maxH-marginH)*0.66f); - float h=(maxW-2*marginW)/(ratios.get(1)+ratios.get(2)+ratios.get(3)); + float hCover=Math.min(MAX_WIDTH/ratios.get(0), (MAX_HEIGHT-GAP)*0.66f); + float h=(MAX_WIDTH-2*GAP)/(ratios.get(1)+ratios.get(2)+ratios.get(3)); float w0=h*ratios.get(1); float w1=h*ratios.get(2); float w2=h*ratios.get(3); - h=Math.min(maxH-hCover-marginH, h); + h=Math.min(MAX_HEIGHT-hCover-GAP, h); if(hCover+h tries=new HashMap<>(); // One line - int firstLine, secondLine, thirdLine; - tries.put(new int[]{firstLine=cnt}, new float[]{calculateMultiThumbsHeight(ratiosCropped, maxW, marginW)}); + int firstLine, secondLine; + tries.put(new int[]{cnt}, new float[]{calculateMultiThumbsHeight(ratiosCropped, MAX_WIDTH, GAP)}); // Two lines for(firstLine=1; firstLine<=cnt-1; firstLine++){ - tries.put(new int[]{firstLine, secondLine=cnt-firstLine}, new float[]{ - calculateMultiThumbsHeight(ratiosCropped.subList(0, firstLine), maxW, marginW), - calculateMultiThumbsHeight(ratiosCropped.subList(firstLine, ratiosCropped.size()), maxW, marginW) + tries.put(new int[]{firstLine, cnt-firstLine}, new float[]{ + calculateMultiThumbsHeight(ratiosCropped.subList(0, firstLine), MAX_WIDTH, GAP), + calculateMultiThumbsHeight(ratiosCropped.subList(firstLine, ratiosCropped.size()), MAX_WIDTH, GAP) } ); } @@ -200,23 +197,23 @@ public class PhotoLayoutHelper{ // Three lines for(firstLine=1; firstLine<=cnt-2; firstLine++){ for(secondLine=1; secondLine<=cnt-firstLine-1; secondLine++){ - tries.put(new int[]{firstLine, secondLine, thirdLine=cnt-firstLine-secondLine}, new float[]{ - calculateMultiThumbsHeight(ratiosCropped.subList(0, firstLine), maxW, marginW), - calculateMultiThumbsHeight(ratiosCropped.subList(firstLine, firstLine+secondLine), maxW, marginW), - calculateMultiThumbsHeight(ratiosCropped.subList(firstLine+secondLine, ratiosCropped.size()), maxW, marginW) + tries.put(new int[]{firstLine, secondLine, cnt-firstLine-secondLine}, new float[]{ + calculateMultiThumbsHeight(ratiosCropped.subList(0, firstLine), MAX_WIDTH, GAP), + calculateMultiThumbsHeight(ratiosCropped.subList(firstLine, firstLine+secondLine), MAX_WIDTH, GAP), + calculateMultiThumbsHeight(ratiosCropped.subList(firstLine+secondLine, ratiosCropped.size()), MAX_WIDTH, GAP) } ); } } - // Looking for minimum difference between thumbs block height and maxH (may probably be little over) + // Looking for minimum difference between thumbs block height and MAX_HEIGHT (may probably be little over) int[] optConf=null; float optDiff=0; for(int[] conf : tries.keySet()){ float[] heights=tries.get(conf); - float confH=marginH*(heights.length-1); + float confH=GAP*(heights.length-1); for(float h : heights) confH+=h; - float confDiff=Math.abs(confH-maxH); + float confDiff=Math.abs(confH-MAX_HEIGHT); if(conf.length>1){ if(conf[0]>conf[1] || conf.length>2 && conf[1]>conf[2]){ confDiff*=1.1; @@ -233,7 +230,7 @@ public class PhotoLayoutHelper{ float[] optHeights=tries.get(optConf); int k=0; - result.width=Math.round(maxW); + result.width=MAX_WIDTH; result.rowSizes=new int[optHeights.length]; result.tiles=new TiledLayoutResult.Tile[thumbs.size()]; float totalHeight=0f; @@ -251,7 +248,7 @@ public class PhotoLayoutHelper{ ArrayList row=new ArrayList<>(); for(int j=0; j0; i--){ @@ -287,7 +284,7 @@ public class PhotoLayoutHelper{ columnOffset+=tile.colSpan; } } - result.height=Math.round(totalHeight+marginH*(optHeights.length-1)); + result.height=Math.round(totalHeight+GAP*(optHeights.length-1)); } return result; diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/views/MediaGridLayout.java b/mastodon/src/main/java/org/joinmastodon/android/ui/views/MediaGridLayout.java index a93fc627..bd6b297b 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/views/MediaGridLayout.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/views/MediaGridLayout.java @@ -16,7 +16,7 @@ public class MediaGridLayout extends ViewGroup{ private static final String TAG="MediaGridLayout"; public static final int MAX_WIDTH=400; // dp - private static final int GAP=1; // dp + private static final int GAP=2; // dp private PhotoLayoutHelper.TiledLayoutResult tiledLayout; private int[] columnStarts=new int[10], columnEnds=new int[10], rowStarts=new int[10], rowEnds=new int[10]; @@ -41,6 +41,9 @@ public class MediaGridLayout extends ViewGroup{ } int width=Math.min(V.dp(MAX_WIDTH), MeasureSpec.getSize(widthMeasureSpec)); int height=Math.round(width*(tiledLayout.height/(float)PhotoLayoutHelper.MAX_WIDTH)); + if(tiledLayout.widthmaxWidth){ xOffset=(r-l)/2-maxWidth/2;