PS在使用脚本生成nft艺术品的踩坑之旅

214 阅读1分钟

PS在使用脚本生成nft艺术品的踩坑之旅

  • 主要功能是生成一个 HashLips 艺术生成器,让用户可以选择生成多少图像、集合的名称和每个图像应该具有的不同特征数量的一个脚本。
  • 第一个坑就是ps识别不出一些内置函数,例如 indexOf(),add(),includes().等等这些已经写好的方法,想使用就必须写一个辅助函数,在你需要用的地方调用这个辅助函数。
  • 第二个坑就是在生成图片的时候,图层的命名不可以用中文,这会导致生成图片的Metadata不识别,导致写不到JSON中。
  • 第三个坑也是中文的问题,脚本的一些注释必须使用英文,中文会报很离谱的错误
综上就是在使用脚本所遇到的坑人的地方
//辅助函数
function indexOf(Array, element) {
  for (var i = 0; i < Array.length; i++) {
    if (Array[i] == element) {
      return i
    }
  }
  return -1;
}
function main() {
  var continueConfirmation = confirm(
    "You are about to use the HashLips art generator. Are you sure you want to continue?"
  );

  if (!continueConfirmation) return;
  alert("Layers do not support Chinese naming")

  var supply = prompt("How many images do you want to generate?", "10");

  var name = prompt("What is the name of your collection?", "");

  var numDifferences_x = prompt("How many different features should each image have?", "3");

  alert(
    supply +
    " images will be generated, so sit back relax and enjoy the art being generated."
  );

  var groups = app.activeDocument.layerSets;
  resetLayers(groups);

  var parts = [];
  for (var i = 0; i < groups.length; i++) {
    var arr = [];
    for (var j = 0; j < groups[i].layers.length; j++) {
      arr.push(j)
    }
    parts.push(arr);
  }


  var numDifferences = numDifferences_x;

  var generatedImages = generateImages(parts, supply, numDifferences);

  for (var i = 0; i < generatedImages.length; i++) {
    var obj = {};
    obj.name = name + "#" + (i + 1);
    obj.image = "To be replaced";
    obj.edition = i + 1;
    obj.attributes = [];
    for (var j = 0; j < generatedImages[i].length; j++) {
      var groupidx = j;
      var layeridx = generatedImages[i][j];
      groups[groupidx].layers[layeridx].visible = true;
      obj.attributes.push({
        trait_type: groups[groupidx].name,
        value: groups[groupidx].layers[layeridx].name
      })
    }
    saveMetadata(obj, name);
    saveImage(obj, name);
    resetLayers(groups);
  }
  alert("Generation process is complete.");
}

function resetLayers(_groups) {
  for (var i = 0; i < _groups.length; i++) {
    _groups[i].visible = true;
    for (var j = 0; j < _groups[i].layers.length; j++) {
      _groups[i].layers[j].visible = false;

    }
  }
}

function saveImage(_obj, _name) {
  var saveFile = new File(toFolder("build/" + _name + "/images") + "/" + _obj.edition + ".png");
  exportOptions = new ExportOptionsSaveForWeb();
  exportOptions.format = SaveDocumentType.PNG;
  exportOptions.PNG24 = false;
  exportOptions.transparency = true;
  exportOptions.interlaced = false;
  app.activeDocument.exportDocument(
    saveFile,
    ExportType.SAVEFORWEB,
    exportOptions
  );
}

function saveMetadata(_data, _name) {
  var file = new File(toFolder("build/" + _name + "/metadata") + "/" + _data.edition + ".json");
  file.open("w");
  file.write(JSON.stringify(_data));
  file.close();
}

function toFolder(_name) {
  var path = app.activeDocument.path;
  var folder = new Folder(path + "/" + _name);
  if (!folder.exists) {
    folder.create();
  }
  return folder;
}

function generateImages(partsArray, _supply, _numDifferences) {
  var images = [];
  var repeatTimes = 0;
  while (images.length < _supply) {

    repeatTimes++;
    if (repeatTimes > 5000) {
      break;
    }

    // var combinationIndex = Math.floor(Math.random() * allCombinations.length);
    // var combinationIndex = idx;
    var combination = [];
    for (var i = 0; i < partsArray.length; i++) {
      var midx = parseInt(Math.random() * partsArray[i].length);
      combination.push(midx);
    }
    var canbePush = true;
    for (var i = 0; i < images.length; i++) {
      var existingCombination = images[i];
      var differences = getDifferences(combination, existingCombination, _numDifferences);
      if (differences < _numDifferences) {
        canbePush = false;
        break;
      }
    }

    if (canbePush) {
      repeatTimes = 0;
      images.push(combination);
    }
  }
  return images;
}


function getDifferences(combination1, combination2, diff) {
  var differences = 0;
  for (var i = 0; i < combination1.length; i++) {
    if (combination1[i] !== combination2[i]) {
      differences++;
      if (differences >= diff) {
        break;
      }
    }
  }
  return differences;
}

function compareArrays(arr1, arr2, diff) {
  var count = 0;

  for (var i = 0; i < arr1.length; i++) {
    var diffBits = arr1[i] ^ arr2[i];

    while (diffBits !== 0) {
      if (diffBits & 1) {
        count++;
        if (count >= diff) {
          return true;
        }
      }
      diffBits >>= 1;
    }
  }

  return false;
}



main();