前言 NFT是前两年火起来的,被大家称为是去中心化的非同质化代币,是具有唯一性的数字资产加密货币令牌,并且是可以买卖的!
这是一场资本家的狂欢泡沫还是致富风口?
咱不知道,就是单纯的最近想自己玩一玩,弄一套上架到NFT交易平台上去看看2333..
然后自己p好了素材,苦于找不到批量生成工具,找了一圈发现网络上有很多js和python的脚本。
但是我自己下载下来运行后发现,不是缺这个模块就是缺那个环境没有部署,更难受的是安装模块还不成功!
最后就自己在Android上去实现了
下面直接看怎么实现的:
Android实现图片合成
数组排列组合 先把每个素材保存到单独的数组里,然后把全部数组合并为一个数组:
1 2 3 4 5 6 7 allList.add(arr_1); allList.add(arr_2); allList.add(arr_3); ... ...
复制代码
排列组合:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 /** * 算法,非递归计算所有组合 * @param inputList 所有数组的列表 * allList_new:排列组合后的新数组 * * */ public void def_calculateCombination(List<List<String>> inputList) { List<Integer> combination = new ArrayList<Integer>(); allList_new.clear(); int n=inputList.size(); for (int i = 0; i < n; i++) { combination.add(0); } int i=0; boolean isContinue=false; do{ List<String> List = new ArrayList<>(); //打印一次循环生成的组合 for (int j = 0; j < n; j++) { Log.e("=========>>>", "" + inputList.get(j).get(combination.get(j))); List.add("" + inputList.get(j).get(combination.get(j))); } Log.e("=========", "====下一组===="); allList_new.add(List); i++; combination.set(n - 1, i); for (int j = n - 1; j >= 0; j--) { if (combination.get(j) >= inputList.get(j).size()) { combination.set(j, 0); i = 0; if (j - 1 >= 0) { combination.set(j - 1, combination.get(j - 1) + 1); } } } isContinue = false; for (Integer integer : combination) { if (integer != 0) { isContinue = true; } } }while (isContinue); }
复制代码
图片合成 图片合成,返回合成后的新图片Bitmap:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 /** * * @param background 背景图 * @param body 前景图 * @return */ public Bitmap def_combineBitmap(Bitmap background, Bitmap body) { if (background == null) { return null; } int bgWidth = background.getWidth(); int bgHeight = background.getHeight(); /* int fgWidth = body.getWidth(); int fgHeight = body.getHeight(); */ Bitmap newmap = Bitmap.createBitmap(bgWidth, bgHeight, Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(newmap); //添加每个素材图片到画布 if (background != null) { canvas.drawBitmap(background, 0, 0, null);//参数2和3是设置贴图的xy坐标位置 } if (body != null) { canvas.drawBitmap(body, 0, 0, null); } //更多素材可以继续在后面添加 canvas.save(); canvas.restore(); return newmap; }
复制代码
保存图片到手机 保存图片到sd卡指定目录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 public void def_savePic(Bitmap btImage) { if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { FileOutputStream out = null; // 获取SDCard指定目录下 String sdCardDir = Environment.getExternalStorageDirectory() + "/NFT/"; File dirFile = new File(sdCardDir); //目录转化成文件夹 if (!dirFile .exists()) { //如果不存在,那就建立这个文件夹 dirFile .mkdirs(); } File file = new File(sdCardDir, "NFT" + System.currentTimeMillis() + ".png");// 在SDcard的目录下创建图片文,以当前时间为其命名 try { out = new FileOutputStream(file); btImage.compress(Bitmap.CompressFormat.PNG, 100, out); //System.out.println("___保存到_sd_指定目录文件夹___"); } catch (FileNotFoundException e) { e.printStackTrace(); } try { out.flush(); out.close(); } catch (IOException e) { e.printStackTrace(); } //Toast.makeText(MainActivity.this, "保存已经至" + sdCardDir + "目录文件夹下", Toast.LENGTH_SHORT).show(); } }
复制代码
保存图片需要SD卡写入的权限,别忘了在 AndroidManifest.xml
中添加!
附加:系统文件管理器选择文件素材并返回路径Uri 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 //存放需要过滤的类型的类 public class MimeType { /* public static final String DOC = "application/msword"; public static final String DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"; public static final String XLS = "application/vnd.ms-excel"; public static final String XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; public static final String PPT = "application/vnd.ms-powerpoint"; public static final String PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation"; public static final String PDF = "application/pdf"; public static final String PNG = "image/png"; */ public static final String JPG = "image/*"; } //选择文件 private void def_performFileSearch() { Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); //允许多选 长按多选 intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true); //不限制选取类型 intent.setType("*/*"); //如果想给选择器添加过滤的文件类型,只需要添加如下代码就可以了 String[] mimeTypes = { /* MimeType.DOC, MimeType.DOCX, MimeType.PDF, MimeType.PPT, MimeType.PPTX, MimeType.XLS, MimeType.XLSX, MimeType.PNG,*/ MimeType.JPG }; intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes); startActivityForResult(intent, 1); //第二个参数必须是大于0的,才会响应onActivityResult()回调函数 } //接收选择文件后的返回值 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case 1: if (resultCode == Activity.RESULT_OK && data != null) { //单选选了一个文件后返回 if (data.getData() != null) { String uri = def_handleSingleDocument(data); //数据uri } else { //多选后返回 ClipData clipData = data.getClipData(); if (clipData != null) { Uri[] uris = new Uri[clipData.getItemCount()]; for (int i = 0; i < clipData.getItemCount(); i++) { uris[i] = clipData.getItemAt(i).getUri(); } //数据uris } } } break; } } //将uri转换为我们需要的path,多选类似 private String def_handleSingleDocument(Intent data) { Uri uri = data.getData(); String filePath = null; try { filePath = MyFileUtils.getPath(this, uri); } catch (Exception e) {} return filePath; }
复制代码
基本上,通关上面这些关键函数,就完全可以实现自己做一个“NFT生成器”App了。
结语 (PS:NFT还会跟当年的比特币那样火起来吗,还是泡沫破灭呢,值得深思emmm…)
OK,今天就这样,感谢阅读。
么么哒~~