在正式写程序之前让我先来看看效果:

对了,这个程序的效果就是生成一个具有你想要的“contributions in the last year”图表的html页面。
当然,html文件,而不是你在Github上面个人主页中的实际的页面。
当然,你可以通过个人努力达到效果(我之前就见过一个I 心 U,但是暂时没有找到出处),不过那需要非常努力和耐性,并且那么做的话收获更多(如果不是仅仅为了那么做而commit+push的话),所以这里介绍一个程序来实现这种方法。
接下来我将用Java来编写程序,主要分为两个步骤:

  1. 下载网页源代码
  2. 根据自己设计的字体替换网页中对应的内容

其中第二步有很多现有的工具,比如Jsoup,但是可以用正则表达式直接解决,后来我发现一个写起来比较方便的方法,因为我发现每一种颜色对应一个fill元素,所以可以直接从fill元素下手。
我把设计的字体保存在了文件picture-fonts.txt(是一个只有字符"0"和"1"的字符文件)中,并把每个字符在picture-fonts.txt中的位置保存在了position.txt中。
他们的预期效果如下:

这意味着在这里你暂时只能达到“ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789”的效果。
“contributions in the last year”列表里面一共有7行53列,为了保(tou)险(lan)这里就先不去动最后一列了。所以我们有7行52列可以用,所以这个程序将会输出最多的我们想要的结果。
程序的代码就一个,内容如下:

package fungithub;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; public class FunGithub { private static Map<String, Word> wordMap = new HashMap<String, Word>();
private static int[][] picNumber = new int[1000][30]; public static void main(String[] args) {
if (args.length != 2) {
System.err.println("usage : <username> <words>");
System.exit(1);
}
solve(args[0], args[1]);
} public static void solve(String username, String words) {
words = words.toUpperCase();
try (
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(System.getProperty("user.dir") + "/picture-fonts.txt"), "utf-8"))
) {
int idx = 0;
String line = null;
while ((line = br.readLine()) != null) {
line = line.trim();
if (line.length() == 0) continue;
int len = line.length();
char[] ch = line.toCharArray();
for (int i = 0; i < len; i ++) {
char c = ch[i];
picNumber[idx][i] = (int) c - (int)'0';
}
idx ++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
try (
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(System.getProperty("user.dir") + "/position.txt"), "utf-8"))
) {
String line = null;
while ((line = br.readLine()) != null) {
line = line.trim();
if (line.length() == 0) continue;
Word temp = new Word(line);
wordMap.put(temp.getC(), temp);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
} List<Integer> allWords = new ArrayList<Integer>();
int i;
for (i = 0; i < words.length(); i ++) {
String oneWordString = String.format("%c", words.charAt(i));
Word oneWord = wordMap.get(oneWordString);
if (oneWord == null) {
System.err.println(oneWordString + " not exists!");
continue;
}
List<Integer> tmpWordsList = oneWord.getWordsList();
if (allWords.size() + tmpWordsList.size() > 52 * 7)
break;
else {
allWords.addAll(tmpWordsList);
if (allWords.size() + 7 <= 52 * 7)
for (int j = 0; j < 7; j ++)
allWords.add(0);
}
}
System.out.println("\"" + words.substring(0, i) +"\" solved!");
int delta = 52 * 7 - allWords.size();
for (int j = 0; j < delta; j ++) allWords.add(0);
// allWords -- the list with 52 * 7 words generated. // download url content
URL url = null;
HttpURLConnection urlConnection = null;
BufferedReader reader;
String pageContent = "";
try {
url = new URL("https://github.com/" + username);
urlConnection = (HttpURLConnection) url.openConnection();
reader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "utf-8"));
String line;
while ((line = reader.readLine()) != null){
pageContent += line + "\n";
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} pageContent = pageContent.replaceAll("fill=\"#[0-9a-e]{6}\"", "MoON1igHt");
for (int word : allWords) {
String fillStr = null;
if (word == 1) {
fillStr = "fill=\"#1e6823\"";
} else {
double r = Math.random();
if (r <= 0.3) fillStr = "fill=\"#eeeeee\"";
else if (r <= 0.9) fillStr = "fill=\"#d6e685\"";
else if (r <= 0.96) fillStr = "fill=\"#8cc665\"";
else fillStr = "fill=\"#44a340\"";
}
pageContent = pageContent.replaceFirst("MoON1igHt", fillStr);
}
pageContent = pageContent.replaceAll("MoON1igHt", "fill=\"#eeeeee\""); // write content to output html file, here I set it to Desktop, here I am the user "Administrator" on Windows7
String outputFileName = "C:/Users/Administrator/Desktop/" + username + "-" + words + ".html";
try (
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream(outputFileName), "utf-8");
) {
osw.write(pageContent);
} catch (UnsupportedEncodingException | FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} System.out.println(username + "-" + words + ".html successifully generated at desktop!");
} static class Word { private String c;
private int px;
private int py;
private int height;
private int width;
private List<Integer> wordsList; public Word(String line) {
String[] arr = line.split(",");
c = arr[0];
px = Integer.parseInt(arr[1]);
py = Integer.parseInt(arr[2]);
height = Integer.parseInt(arr[3]);
width = Integer.parseInt(arr[4]); // generate wordsList
wordsList = new ArrayList<Integer>();
for (int j = 0; j < width; j ++)
for (int i = 0; i < height; i ++)
wordsList.add(picNumber[px+i][py+j]);
} public String getC() { return c; }
public int getPx() { return px; }
public int getPy() { return py; }
public int getHeight() { return height; }
public int getWidth() { return width; }
public List<Integer> getWordsList() { return wordsList; }
}
}

另外还有2个资源文件,Github项目位置:https://github.com/moonlightpoet/FunGithub 有兴趣可以玩一下。
另外github pages上面放了两个可以看看在线效果(一个I Love you的和一个Fxxk you的):

I Love You
Fxxk You

注:今天找到了知乎上问题的出处

Github恶搞之自定义你的contribution图表的更多相关文章

  1. 4.总结近5周以来的github上的工作情况,以图表方式分析你小组的工作情况、存在的问题及解决的方案。(尤心心)

    4.总结近5周以来的github上的工作情况,以图表方式分析你小组的工作情况.存在的问题及解决的方案. (1)利用github本身的graphs可以清晰的看出小组成员在github上面的交互,可以直接 ...

  2. Github 恶搞教程(一起『玩坏』自己的 Github 吧)

    最近在伯乐在线读到一篇趣文,<如何在 Github『正确』做贡献>,里面各种能人恶搞 Github 的『Public contributions』,下面截取几个小伙伴的战绩: 顺藤摸瓜,发 ...

  3. GitHub pages+自定义域名(腾讯云域名)+cloudflare加速

    本人也是第一次走完整个流程,github pages当然一直有使用,创建也很简单,并且网上教程也比较多:然后是关于自定义域名的问题,自己以前使用过国外的免费域名,然后是直接修改就ok了,然后这次使用了 ...

  4. JHChart 1.1.0 iOS图表工具库中文ReadMe

    JHChart(最新版本1.1.0) 好吧,的确当前的github上已经存有不少的iOS图表工具库,然而,当公司的项目需要图表时,几乎没有哪个第三方能够完全满足我的项目需求.无奈之下,本人不得不花费一 ...

  5. 美丽的Java图表类库

    摘要 在使用java做后台站点的开发张,图表和报表功能都是不可或缺 的.本文推荐了8款最精彩实用的Java图表应用,大部分图表应用的功能都类似,主要在于界面的美观性和使用的灵活性上有一点高低. 正文 ...

  6. 非常有用的GitHub链接

    平常开发工作中,我经常取Github上搜索项目,Clone下来学习使用,在这个过程中,发现了好多比较好的Github地址,记录下来,分享出去. image 非常有用的GitHub链接(顺序不分先后): ...

  7. Chart 图表开源项目总结

    在Android开发中,我们不免会遇到图表展示的需求,以下是本人之前star的悬浮窗的开源项目,供大家参考: 1. WilliamChart:创建图表的Android库 2. HelloCharts: ...

  8. Github使用教程(一)------ 初识Github

    上一节我们解决了Github网站响应慢,加载不完全的情况,接下来我们就要正式开始使用Github了. :好,那我先安装Git,稍后就上传项目. :......你Github网站都看懂了? :还需要看懂 ...

  9. 2019最新Android常用开源库总结(附带github链接)

    前言 收集了一些比较常见的开源库,特此记录(已收录350+).另外,本文将持续更新,大家有关于Android 优秀的开源库,也可以在下面留言. 一 .基本控件 1.TextView HTextView ...

随机推荐

  1. Alpha冲刺(3/10)——2019.4.26

    所属课程 软件工程1916|W(福州大学) 作业要求 Alpha冲刺(3/10)--2019.4.26 团队名称 待就业六人组 1.团队信息 团队名称:待就业六人组 团队描述:同舟共济扬帆起,乘风破浪 ...

  2. vue使用babel+sass出错解决

    按照官网的步骤先将vue项目建立好,这时如果使用lang="babel",lang="scss"会报错. 这时终端进入项目文件夹下输入以下命令: npm ins ...

  3. 原生ajax请求

    $('#send').click(function(){ //请求的5个阶段,对应readyState的值 //0: 未初始化,send方法未调用: //1: 正在发送请求,send方法已调用: // ...

  4. 12、Bootstrap中文文档(其它插件分享)

    给大家介绍一个前端框架让你从此写起前端代码与之先前相比如有神助般的效果拉就是Bootstrap. 本片导航: Bootstrap的下载 css样式的使用 JavaScript 效果的引用 其他前端插件 ...

  5. Jquery如何获取某个元素前(后)的文本内容?

    <span> text here... <a id="target_element">百万创想</a></span> 如何获得a标签 ...

  6. golang的dlv调试工具print打印字符串显示more,无法显示更多

    使用dlv (delve golang调试器)打印字符串无法打印全,只能打印一部分(64个字节),在gdb中有 (gdb) set print elements Argument required ( ...

  7. C++异常处理解析: 异常的引发(throw), 捕获(try catch)、异常安全

    前言: C++的异常处理机制是用于将运行时错误检测和错误处理功能分离的一 种机制(符合高内聚低耦合的软件工程设计要求),  这里主要总结一下C++异常处理的基础知识, 包括基本的如何引发异常(使用th ...

  8. c++中POD类型和non-POD类型

    对于一个array来说: For POD-types, a shallow copy or memcpy of the whole array is good enough, while for no ...

  9. CVPR论文《100+ Times Faster Weighted Median Filter (WMF)》的实现和解析(附源代码)。

    四年前第一次看到<100+ Times FasterWeighted Median Filter (WMF)>一文时,因为他附带了源代码,而且还是CVPR论文,因此,当时也对代码进行了一定 ...

  10. 需要看源码的java类

    1.数据结构相关的类,如String.ArrayList,LinkedList,HashMap和ConcurrentHashMap等等.2.线程并发相关的类,如Synchronized.Reentra ...