Created
February 28, 2012 17:58
-
-
Save zhukov/1934001 to your computer and use it in GitHub Desktop.
VK compose photos
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void processThumbs(int maxW, int maxH){ | |
ArrayList<ThumbAttachment> thumbs=new ArrayList<ThumbAttachment>(); | |
for(Attachment att:attachments) | |
if(att instanceof PhotoAttachment) thumbs.add((ThumbAttachment)att); | |
String orients=""; | |
int[] orients_cnt=new int[3]; | |
ArrayList<Float> ratios=new ArrayList<Float>(); | |
int cnt=thumbs.size(); | |
boolean bad=false; | |
for(ThumbAttachment thumb:thumbs){ | |
float ratio=thumb.getRatio(); | |
if(ratio==-1){ | |
bad=true; | |
} | |
char orient=ratio > 1.2 ? 'w' : (ratio < 0.8 ? 'n' : 'q'); | |
orients+=orient; | |
orients_cnt[oi(orient)]++; | |
ratios.add(ratio); | |
} | |
if(bad || NetworkStateReceiver.disableBigImages){ | |
//Log.e("vk", "BAD!"); | |
return; | |
} | |
float avg_ratio = !ratios.isEmpty() ? sum(ratios) / ratios.size() : 1.0f; | |
float max_w, max_h, margin_w=Global.scale(2), margin_h=Global.scale(2); | |
if(maxW>0){ | |
max_w=maxW; | |
max_h=maxH; | |
}else{ | |
max_w=320; | |
max_h=210; | |
} | |
float max_ratio=(float)max_w/(float)max_h; | |
if(cnt==1){ | |
if(ratios.get(0)>0.5){ | |
thumbs.get(0).setViewSize(max_w, (float)max_w/(float)ratios.get(0), false, false); | |
}else{ | |
thumbs.get(0).setViewSize(max_w, max_w*2, false, false); | |
} | |
} | |
else if(cnt==2){ | |
if(orients.equals("ww") && avg_ratio > 1.4 * max_ratio && (ratios.get(1) - ratios.get(0)) < 0.2){ | |
float w = max_w; | |
float h = Math.min((float)w / ratios.get(0), Math.min((float)w / ratios.get(1), (max_h - margin_h) / 2.0f)); | |
thumbs.get(0).setViewSize(w, h, true, false); | |
thumbs.get(1).setViewSize(w, h, false, false); | |
}else if(orients.equals("ww") || orients.equals("qq")){ | |
float w = ((max_w - margin_w) / 2); | |
float h = Math.min(w / ratios.get(0), Math.min(w / ratios.get(1), max_h)); | |
thumbs.get(0).setViewSize(w, h, false, false); | |
thumbs.get(1).setViewSize(w, h, false, false); | |
}else{ | |
float w0 = ((max_w - margin_w) / ratios.get(1) / (1 / ratios.get(0) + 1 / ratios.get(1))); | |
float w1 = (max_w - w0 - margin_w); | |
float h = Math.min(max_h, Math.min(w0 / ratios.get(0), w1 / ratios.get(1))); | |
thumbs.get(0).setViewSize(w0, h, false, false); | |
thumbs.get(1).setViewSize(w1, h, false, false); | |
} | |
} | |
else if(cnt==3){ | |
if (/*(ratios.get(0) > 1.2 * max_ratio || avg_ratio > 1.5 * max_ratio) &&*/ orients.equals("www")) { // 2nd and 3rd photos are on the next line | |
float w = max_w; | |
float h_cover = Math.min(w / ratios.get(0), (max_h - margin_h) * 0.66f); | |
thumbs.get(0).setViewSize(w, h_cover, true, false); | |
w = ((max_w - margin_w) / 2); | |
float h = Math.min(max_h - h_cover - margin_h, Math.min(w / ratios.get(1), w / ratios.get(2))); | |
thumbs.get(1).setViewSize(w, h, false, false); | |
thumbs.get(2).setViewSize(w, h, false, false); | |
} else { // 2nd and 3rd photos are on the right part | |
int h = (int)max_h; | |
int w_cover = (int)Math.min(h * ratios.get(0), (max_w - margin_w) * 0.75); | |
thumbs.get(0).setViewSize(w_cover, h, false, false); | |
float h1 = (ratios.get(1) * (max_h - margin_h) / (ratios.get(2) + ratios.get(1))); | |
float h0 = (max_h - h1 - margin_h); | |
float w = Math.min(max_w - w_cover - margin_w, Math.min(h1 * ratios.get(2), h0 * ratios.get(1))); | |
thumbs.get(1).setViewSize(w, h0, false, true); | |
thumbs.get(2).setViewSize(w, h1, false, true); | |
} | |
} | |
else if (cnt == 4) { | |
if (/*(ratios.get(0) > 1.2 * max_ratio || avg_ratio > 1.5 * $max_ration) &&*/ orients.equals("wwww")) { // 2nd, 3rd and 4th photos are on the next line | |
int w = (int)max_w; | |
int h_cover = (int)Math.min(w / ratios.get(0), (max_h - margin_h) * 0.66); | |
thumbs.get(0).setViewSize(w, h_cover, true, false); | |
int h = (int)((max_w - 2 * margin_w) / (ratios.get(1) + ratios.get(2) + ratios.get(3))); | |
int w0 = (int)(h * ratios.get(1)); | |
int w1 = (int)(h * ratios.get(2)); | |
int w2 = (int)(h * ratios.get(3)); | |
h = (int)Math.min(max_h - h_cover - margin_h, h); | |
thumbs.get(1).setViewSize(w0, h, false, false); | |
thumbs.get(2).setViewSize(w1, h, false, false); | |
thumbs.get(3).setViewSize(w2, h, false, false); | |
} else { // 2nd, 3rd and 4th photos are on the right part | |
int h = (int)max_h; | |
int w_cover = (int)Math.min(h * ratios.get(0), (max_w - margin_w) * 0.66); | |
thumbs.get(0).setViewSize(w_cover, h, false, false); | |
int w = (int)((max_h - 2 * margin_h) / (1 / ratios.get(1) + 1 / ratios.get(2) + 1 / ratios.get(3))); | |
int h0 = (int)(w / ratios.get(1)); | |
int h1 = (int)(w / ratios.get(2)); | |
int h2 = (int)(w / ratios.get(3)+margin_h); | |
w = (int)Math.min(max_w - w_cover - margin_w, w); | |
thumbs.get(1).setViewSize(w, h0, false, true); | |
thumbs.get(2).setViewSize(w, h1, false, true); | |
thumbs.get(3).setViewSize(w, h2, false, true); | |
} | |
} | |
else{ | |
ArrayList<Float> ratios_cropped = new ArrayList<Float>(); | |
if (avg_ratio > 1.1) { | |
for(float ratio:ratios) { | |
ratios_cropped.add(Math.max(1.0f, ratio)); | |
} | |
} else { | |
for (float ratio:ratios) { | |
ratios_cropped.add(Math.min(1.0f, ratio)); | |
} | |
} | |
HashMap<String, float[]> tries = new HashMap<String, float[]>(); | |
// One line | |
int first_line, second_line, third_line; | |
tries.put((first_line=cnt)+"", new float[]{calculateMultiThumbsHeight(ratios_cropped, max_w, margin_w)}); | |
// Two lines | |
for (first_line = 1; first_line <= cnt - 1; first_line++) { | |
tries.put(first_line+","+(second_line = cnt - first_line), new float[]{ | |
calculateMultiThumbsHeight(ratios_cropped.subList(0, first_line), max_w, margin_w), | |
calculateMultiThumbsHeight(ratios_cropped.subList(first_line, ratios_cropped.size()), max_w, margin_w) | |
} | |
); | |
} | |
// Three lines | |
for (first_line = 1; first_line <= cnt - 2; first_line++) { | |
for (second_line = 1; second_line <= cnt - first_line - 1; second_line++) { | |
tries.put(first_line+","+second_line+","+(third_line = cnt - first_line - second_line), new float[]{ | |
calculateMultiThumbsHeight(ratios_cropped.subList(0, first_line), max_w, margin_w), | |
calculateMultiThumbsHeight(ratios_cropped.subList(first_line, first_line+second_line), max_w, margin_w), | |
calculateMultiThumbsHeight(ratios_cropped.subList(first_line + second_line, ratios_cropped.size()), max_w, margin_w) | |
} | |
); | |
} | |
} | |
// Looking for minimum difference between thumbs block height and max_h (may probably be little over) | |
String opt_conf = null; | |
float opt_diff = 0; | |
float opt_height = 0; | |
float opt_h; | |
Set<String> keys=tries.keySet(); | |
for (String conf:keys) { | |
float[] heights=tries.get(conf); | |
float conf_h = margin_h * (heights.length - 1); | |
for(float h:heights) conf_h+=h; | |
float conf_diff = Math.abs(conf_h - max_h); | |
if (conf.indexOf(',') != -1) { | |
String[] conf_nums = conf.split(","); | |
if (Integer.parseInt(conf_nums[0]) > Integer.parseInt(conf_nums[1]) || | |
conf_nums.length>2 && Integer.parseInt(conf_nums[1]) > Integer.parseInt(conf_nums[2])) { | |
conf_diff *= 1.1; | |
} | |
} | |
if (opt_conf == null || conf_diff < opt_diff) { | |
opt_conf = conf; | |
opt_diff = conf_diff; | |
opt_h = conf_h; | |
} | |
} | |
boolean breakNext=false; | |
// Generating optimal HTML | |
ArrayList<ThumbAttachment> thumbs_remain = (ArrayList<ThumbAttachment>) thumbs.clone(); | |
ArrayList<Float> ratios_remain = (ArrayList<Float>) ratios_cropped.clone(); | |
String[] chunks = opt_conf.split(","); | |
float[] opt_heights = tries.get(opt_conf); | |
int last_row = chunks.length - 1; | |
int k=0; | |
for (int i=0;i<chunks.length;i++) { | |
int line_chunks_num=Integer.parseInt(chunks[i]); | |
ArrayList<ThumbAttachment> line_thumbs = new ArrayList<ThumbAttachment>(); | |
for(int j=0;j<line_chunks_num;j++) line_thumbs.add(thumbs_remain.remove(0)); | |
float line_height = opt_heights[k]; | |
k++; | |
int last_column = line_thumbs.size() - 1; | |
for (int j=0;j<line_thumbs.size();j++) { | |
ThumbAttachment thumb=line_thumbs.get(j); | |
float thumb_ratio = ratios_remain.remove(0); | |
thumb.setViewSize((int)(thumb_ratio * line_height), (int)line_height, j==last_column, false); | |
} | |
} | |
} | |
} | |
private int oi(char o){ | |
switch(o){ | |
case 'w': | |
return 0; | |
case 'n': | |
return 1; | |
case 'q': | |
return 2; | |
} | |
return 0; | |
} | |
private float sum(List<Float> a){ | |
float sum=0; | |
for(float f:a) sum+=f; | |
return sum; | |
} | |
private float calculateMultiThumbsHeight(List<Float> ratios, float width, float margin) { | |
return (width - (ratios.size() - 1) * margin) / sum(ratios); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment