最终效果对比
图片替换前: 图片显示有好有坏,能否显示,全凭运气
![](https://img.haomeiwen.com/i3203841/5f29a136048eae61.gif)
图片替换后: 所有大图正常显示!
![](https://img.haomeiwen.com/i3203841/cd9ae9e9e533b4d1.gif)
本项目永久开源地址
https://github.com/zhaoolee/replace_readme_md_image
痛点: Github的README.md展示图片效果并不完美
为了让项目演示更生动形象, 我们可以往README.md中插入一些图片
但Github会对README.md中的站外图片会进行地址转换,如果图片尺寸很小,这种转换完全没有问题, 但如果图片尺寸稍大, github的只能转换出半张图, 图片展示的效果极差
比如 将https://v2fy.com/asset/bilibili_wallpaper/3203841-ee56972a7e14ff43.png
转换为https://camo.githubusercontent.com/e2b664d80ebe666681016c66d2b42ee9f8f9ec3e6c73d3a34accdaadba84b23a/687474703a2f2f763266792e636f6d2f61737365742f62696c6962696c695f77616c6c70617065722f333230333834312d656535363937326137653134666634332e706e67
![](https://img.haomeiwen.com/i3203841/3dfc0435c2497ba6.gif)
原图
![](https://img.haomeiwen.com/i3203841/0f47e58729a5efd3.png)
被github转换后的图片
![](https://img.haomeiwen.com/i3203841/bccda1a9e580e61b.png)
如何解决README.md中大图展示不完美的问题?
将图片上传的到github即可!
我们可以将README.md中的图片存储到仓库根目录的README文件夹, 然后用图片在github的url, 替换原有的图片链接.
我分析了一下github 仓库中包含图片的url的规则
https://raw.githubusercontent.com/
+ 用户名
+ /
+ 仓库名
+ /master/
+ 相对仓库根目录的文件夹路径
+ /
+ 图片名
;
如果图片名称为1610212776529GNazs3pP.gif, 图片存储在 zhaoolee
的 EasyTypora
仓库的 README
文件夹下,那它的最终url为
https://raw.githubusercontent.com/zhaoolee/EasyTypora/master/README/1610212776529GNazs3pP.gif
但是手工替换所有的图片太累了, 于是我写了一个自动化的程序
- 程序支持转换网络图片为github路径
- 程序支持转换本地路径图片为github路径
- 程序自动读取仓库下的
.git/config
,获取用户名和仓库名称 - 自动判断前缀, 对于已经转换的图片, 重复运行程序无需重新爬取,节约流量!
const request = require("request");
const fs = require("fs-extra");
const path = require("path");
// 读取用户输入
async function readline_sync() {
const readline = require('readline').createInterface({
input: process.stdin,
output: process.stdout
})
return new Promise((resolve, reject) => {
readline.question(``, data => {
readline.close();
resolve(data)
})
});
}
async function get_github_username_repositories_name() {
// 查看.git文件夹是否存在
let exist = fs.existsSync(path.join(__dirname, ".git", "config"));
// 如果.git存在则读取username和repositories_name
let username = "";
let repositories_name = "";
let url = "";
if (exist) {
let config_content = String(fs.readFileSync(path.join(__dirname, ".git", "config")))
let re_n_t = /\n|\t/;
let config_content_list = config_content.split(re_n_t)
for (let i = 0, config_content_list_length = config_content_list.length; i < config_content_list_length; i++) {
if (config_content_list[i].indexOf("url") === 0) {
url = config_content_list[i].split("url = ")[1];
url = url.split(".git")[0]
let url_info = url.split("/");
// console.log(url_info);
url_info.reverse();
username = url_info[1];
repositories_name = url_info[0];
}
}
}
// 如果.git不存在则要求输入username和repositories_name
if (exist === false) {
console.log("请输入github用户名:");
username = await readline_sync();
console.log("请输入仓库名:");
repositories_name = await readline_sync();
}
console.log(username, repositories_name);
return new Promise((resolve, reject) => {
resolve({ username: username, repositories_name: repositories_name })
})
}
function get_img_url_list_in_md(md_path) {
const md_content = String(fs.readFileSync(md_path));
re_md_img = /\!\[(.*)\]\((.*)\)/g;
let md_img_list = md_content.match(re_md_img);
console.log(md_img_list);
let img_url_list = [];
for (let i = 0, md_img_list_length = md_img_list.length; i < md_img_list_length; i++) {
img_url = md_img_list[i].match(/(.*)\((.*)\)/)[2];
img_url_list.push(img_url);
}
return img_url_list;
}
// 创建随机数函数
// 随机产生字符串
function randomString(e) {
e = e || 32;
var t = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz012345678",
a = t.length,
n = "";
for (i = 0; i < e; i++) n += t.charAt(Math.floor(Math.random() * a));
return n
}
function download_img_to_readme_dir(img_url, pre_image_url){
let new_img_url = "";
return new Promise((resolve, reject)=>{
// 如果以http开头,则进行下载
if(img_url.indexOf("http") === 0){
try {
let img_url_info = img_url.split(".")
img_url_info.reverse();
let ext = img_url_info[0];
let new_img_name = Date.now() + randomString(8) + "." + ext;
request.get(img_url).pipe(fs.createWriteStream(path.join(__dirname, "README", new_img_name))).on("close", function(err){
new_img_url = pre_image_url + new_img_name;
resolve(new_img_url);
});
}catch(e){
console.log(e);
new_img_url = img_url;
resolve(new_img_url);
}
}
// 如果不以http开头,则是本地图片,进行拷贝即可
else {
let img_url_info = img_url.split(".")
img_url_info.reverse();
let ext = img_url_info[0];
let new_img_name = Date.now() + randomString(8) + "." + ext;
fs.createReadStream(img_url).pipe(fs.createWriteStream(path.join(__dirname, "README", new_img_name))).on("close", function(err){
new_img_url = pre_image_url + new_img_name;
resolve(new_img_url);
});
}
})
}
function replace_readme_info ( src_text, dest_text) {
// 获取README.md原始信息
let readme_content = String(fs.readFileSync(path.join(__dirname, "README.md")));
let new_readme_content = readme_content.replace(src_text, dest_text);
fs.writeFileSync(path.join(__dirname, "README.md"), new_readme_content);
}
async function main() {
// 获取仓库的用户名和仓库名
let { username, repositories_name } = await get_github_username_repositories_name();
// console.log(username_repositories_name);
// username = username_repositories_name.username;
// repositories_name = username_repositories_name.repositories_name;
console.log(username, repositories_name);
// 备份README.md为README_BEFORE.md
fs.copyFileSync(path.join(__dirname, "README.md"), path.join(__dirname, "README_BEFORE.md"))
// 拼接README图片前缀
let pre_image_url = "https://raw.githubusercontent.com/" + username + "/" + repositories_name + "/master/README/"
// 获取README.md里面的所有图片地址列表
let img_url_list = get_img_url_list_in_md(path.join(__dirname, "README.md"));
// 如果README文件夹不存在,则创建README文件夹
if ((fs.existsSync(path.join(__dirname, "README"))) === false) {
fs.mkdirSync(path.join(__dirname, "README"))
}
for (let i = 0, img_url_list_length = img_url_list.length; i < img_url_list_length; i++) {
// 如果图片以pre_image_url开头,则跳过
if (img_url_list[i].indexOf(pre_image_url) === -1) {
// 将图片下载到README文件夹,并生成图片github地址
let new_img_url = await download_img_to_readme_dir(img_url_list[i], pre_image_url);
// 替换README.md内图片地址为github地址
replace_readme_info(img_url_list[i], new_img_url);
console.log("将==》",img_url_list[i] ,"替换为==》",new_img_url);
}
}
}
main();
如何使用本项目
如果是node.js项目
- 将本项目根目录下main.js放入目标项目根目录,运行即可(如果报错依赖包缺失,记得npm i request fs-extra -D 补包)
- main.js程序运行完成后, 运行
git add README
git commit -m "新增README图片"
git push
如果是非node.js项目
- 下载本项目,并安装依赖包
git clone https://github.com/zhaoolee/replace_readme_md_image.git
cd replace_readme_md_image
npm i
-
删除本项目下的 REAEME.md 文件和README文件夹和.git文件夹
-
将需要转换的README.md文案件和.git文件夹放入项目根目录, 如果REAMD.md中含本地相对路径的图片文件, 请手动调整路径
-
运行
npm start
, 生成新的README.md文件和README文件夹
- 将README.md文件和README文件夹放入原项目中, 原项目运行
git add README
git commit -m "新增README图片"
git push
网友评论