2013-10-30 30 views
3

以谷歌圖片,flickr照片流等作爲例證。每張圖片都有不同的尺寸+收音機,但它們都在左側+右側排列。如何調整網格中「全部出血」的圖像大小?

我的原始邏輯是在javascript中循環它們,找出當我處於下一幅圖像太寬的時候。然後,我看到我有多少「空間」,並在整個電路板上增加了寬度 - 但我最終使得圖像太寬。

這樣的事情是我在做什麼:

maxwidth = 100; 
width = 0; 
imgs = []; 
foreach image { 
    if (width + image.width > maxwidth) { 
     space = maxwidth - width/imgs.length; 
     foreach imgs { 
      img.width = img.width + space; 
     } 

     imgs = []; 
     width = 0; 
    } 

    imgs.push(image); 
    width += image.width; 
} 

回答

1

這是partition problem;其在照片畫廊的應用在Johannes Treitz的this blog post中討論。建議的解決方案是:

  • 要找到ķ,所需的行數,縮放照片到窗口的高度的一半,總結它們的寬度,通過窗口的寬度鴻溝,然後圓。
  • 照片的縱橫比然後作爲一個集合S的權重。使用現有的線性分區算法找到S優於k的最優分佈。

的博客文章包括以下的CoffeeScript建庫:

viewport_width = $(window).width() 
ideal_height = parseInt($(window).height()/2) 
summed_width = photos.reduce ((sum, p) -> sum += p.get('aspect_ratio') * ideal_height), 0 
rows = Math.round(summed_width/viewport_width) 

if rows < 1 
    # (2a) Fallback to just standard size 
    photos.each (photo) -> photo.view.resize parseInt(ideal_height * photo.get('aspect_ratio')), ideal_height 
else 
    # (2b) Distribute photos over rows using the aspect ratio as weight 
    weights = photos.map (p) -> parseInt(p.get('aspect_ratio') * 100) 
    partition = linear_partition(weights, rows) 

    # (3) Iterate through partition 
    index = 0 
    row_buffer = new Backbone.Collection 
    _.each partition, (row) -> 
    row_buffer.reset() 
    _.each row, -> row_buffer.add(photos.at(index++)) 
    summed_ratios = row_buffer.reduce ((sum, p) -> sum += p.get('aspect_ratio')), 0 
    row_buffer.each (photo) -> photo.view.resize parseInt(viewport_width/summed_ratios * photo.get('aspect_ratio')), parseInt(viewport_width/summed_ratios) 

linear_partition功能的實現如下(see github):

# Linear partition 
# Partitions a sequence of non-negative integers into k ranges 
# Based on Óscar López implementation in Python (http://stackoverflow.com/a/7942946) 
# Also see http://www8.cs.umu.se/kurser/TDBAfl/VT06/algorithms/BOOK/BOOK2/NODE45.HTM 
# Dependencies: UnderscoreJS (http://www.underscorejs.org) 
# Example: linear_partition([9,2,6,3,8,5,8,1,7,3,4], 3) => [[9,2,6,3],[8,5,8],[1,7,3,4]] 

linear_partition = (seq, k) => 
    n = seq.length 

    return [] if k <= 0 
    return seq.map((x) -> [x]) if k > n 

    table = (0 for x in [0...k] for y in [0...n]) 
    solution = (0 for x in [0...k-1] for y in [0...n-1]) 
    table[i][0] = seq[i] + (if i then table[i-1][0] else 0) for i in [0...n] 
    table[0][j] = seq[0] for j in [0...k] 
    for i in [1...n] 
    for j in [1...k] 
     m = _.min(([_.max([table[x][j-1], table[i][0]-table[x][0]]), x] for x in [0...i]), (o) -> o[0]) 
     table[i][j] = m[0] 
     solution[i-1][j-1] = m[1] 

    n = n-1 
    k = k-2 
    ans = [] 
    while k >= 0 
    ans = [seq[i] for i in [(solution[n-1][k]+1)...n+1]].concat ans 
    n = solution[n-1][k] 
    k = k-1 

    [seq[i] for i in [0...n+1]].concat ans 
+0

發佈有關算法......你剛剛得到你的粉絲:) – mayankcpdixit

相關問題