如何找到大图像的有损维度

时间:2015-01-30 08:27:39

标签: javascript algorithm

我需要一个函数,它接受两个参数宽度和高度,并返回一个新的宽度和一个新的高度,它们的值减少到100以下。

示例:

  1. w:1920 h:1080 =>返回w:16小时:9
  2. w:1921 h:1080 =>返回w:16小时:9
  3. w:800小时:600 =>返回w:4小时:3
  4. w:100小时:831 =>返回w:1小时:8
  5. w:10小时:2000 =>返回w:1小时:200
  6. w:2047 h:663 =>返回w:102小时:33
  7. 对于标准化的屏幕分辨率,GCD是一种很好的算法,可以找到最大的公约数,但是当我有非标准值时,例如#2例子,它对我来说不是最佳的。

    有没有算法可以解决我的算法问题? (算法应该是有损的,我知道没有损失是不可能的。)

    这是我的GCD算法,适用于标准值:

    function gcd($a, $b) {
        return ($a % $b) ? gcd($b, $a % $b) : $b;
    }
    
    function reduce(w, h) {
        var _gcd = gcd(w, h);
        return [w / _gcd, h / _gcd]
    }
    
    console.log(reduce(800, 600));
    

1 个答案:

答案 0 :(得分:0)

这是一个基于@KarolyHorvath和@spektre

的可能解决方案

分数是存储相关维度的对象键。 此外,添加到数组的分数,然后排序的数组和二进制搜索找到与reduce方法的分数最接近的值。然后它返回压缩的尺寸。

 function binaryIndexOf(searchElement) {
     'use strict';

     var minIndex = 0;
     var maxIndex = this.length - 1;
     var currentIndex;
     var currentElement;
     var resultIndex;

     while (minIndex <= maxIndex) {
         resultIndex = currentIndex = (minIndex + maxIndex) / 2 | 0;
         currentElement = this[currentIndex];

         if (currentElement < searchElement) {
             minIndex = currentIndex + 1;
         } else if (currentElement > searchElement) {
             maxIndex = currentIndex - 1;
         } else {
             return currentIndex;
         }
     }

     return~maxIndex;
 }

 Array.prototype.binaryIndexOf = binaryIndexOf;

 var helper = [],
     data = {};

 for (var i = 1; i < 100; i++) {
     for (var j = 1; j < 100; j++) {
         var d = i / j;
         if (typeof data[d] == 'undefined') {
             data[d] = [i, j];
             helper.push(d);
         }
     }
 }

helper.sort(function (a, b) {
     return a - b
 });

 function reduce(w, h) {
     return data[helper[Math.abs(helper.binaryIndexOf(w / h))]];
 }

 console.log(reduce(1921, 1079));