Kiwi Blog

做一个优秀的普通人


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

如何快速创建一个nodejs-Server项目

发表于 2023-03-24 | 分类于 nodejs |

初始化

1
npm init -y

其中的参数-y表示对于所有询问说Yes。

此时文件夹中会多一个package.json文件,其内容如下:

1
2
3
4
5
6
7
8
9
10
11
{
"name": "server",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}

安装依赖

1
npm install express

执行后可以在命令行中看到如下输出:

1
2
3
4
5
6
added 57 packages, and audited 58 packages in 15s

7 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities

此时package.json中会多个属性:

1
2
3
4
5
{
"dependencies": {
"express": "^4.18.2"
}
}

安装Typescript并创建tsconfig.json

执行如下命令

1
npm install typescript -g

其中 -i表示install, -g表示global。

执行成功后,一般情况下系统可以执行tsc命令,尝试执行:

1
tsc -v

如果报错:

1
2
3
4
5
6
7
tsc : 无法加载文件 C:\nodejs\tsc.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅 https:/go.microsoft.com/fwlink/?LinkID=1351
70 中的 about_Execution_Policies。
所在位置 行:1 字符: 1
+ tsc -version
+ ~~~
+ CategoryInfo : SecurityError: (:) [],PSSecurityException
+ FullyQualifiedErrorId : UnauthorizedAccess

以管理员身份打开powershell,执行命令:set-ExecutionPolicy RemoteSigned

image-20230324162831404

再次在命令行窗口执行

1
2
tsc -v
#output Version 5.0.2

执行成功后,执行如下命令,创建tsconfig.json

1
tsc --init

创建src目录以及index.ts

如图:

image-20230324164307295

在tsconfig.json中添加:

1
2
3
4
5
{
"include": [
"./src"
]
}

安装nodemon

nodemon能够实现在程序代码变更之后自动监听然后重启开发服务。

1
npm install nodemon -g

安装ts-node

以便解析typescript至javascript,这个安装包是为了不用编译直接运行typescript代码

1
npm install ts-node -g

在package.json的scripts中添加命令:

1
"dev": "nodemon --exec ts-node ./src/index -e ts"

在src目录下创建index.ts文件,文件内容可以简单的写一句日志输出:

1
2
// ./src/index.ts
console.log('服务启动')

在命令行中执行:

1
2
npm run dev
# 实际执行: nodemon --exec ts-node ./src/index -e ts

执行效果如下图:

image-20230324173048385

使用Express搭建一个简易的响应服务

命令行中执行如下命令,安装node和express的类型声明。(因为Javascript的.js文件是没有类型的,从而造成Typescript不能识别)

1
npm install -D @types/express @types/node

也有说法是在tsconfig.json中添加一条属性:"allowJs": true,这样做会造成Typescript将Javascript中的所有方法类型全部定义为any,因此不建议这么做。

在src/index.ts中录入以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import express from "express"

const app = express();

// 处理请求
app.get("/list", (req, res) => {
let list = [
{ name: "张三", age: 13 },
{ name: "李四", age: 33},
{ name: "王五", age: 22 }
];
res.json(list); // 将数据返回给服务端
});
app.listen("3000", () => {
console.log("=========服务启动了,在3000端口=========");
});

执行npm run dev,在浏览器中录入接口路径,查看输出结果:

image-20230324174340557

至此,一个简单的Nodejs的Web服务就搭建好了。

参考文献

  1. https://toutiao.io/posts/6yxdar1/preview
  2. https://www.cnblogs.com/goloving/p/16157326.html
  3. https://blog.51cto.com/u_11365839/5050153
  4. https://cloud.tencent.com/developer/article/1940478
  5. https://juejin.cn/post/7089696439692951559

python制作动态字符图

发表于 2023-03-20 | 分类于 python |
阅读全文 »

游戏框架调研记录

发表于 2023-03-13 | 分类于 游戏 |

目录

  • cocos与unity对比
  • 技术储备与掌握程度
    • 个人理解的关键技能
  • 游戏类型或适用场景
  • 其他Cocos的相关内容
  • 开源地址
  • Cocos Creator开发流程
  • 界面介绍
  • 学习教程
阅读全文 »

python3如何处理GIF图片

发表于 2023-03-09 | 分类于 python |

## 最终的实现效果

先来看看我们要实现什么效果:

原图:

处理后:

非灰度的

灰度的

实现思路

理解这一思路需要稍有些图像处理基础。gif实际上是多帧图片按照一定的播放速度逐帧播放,又由于视觉停留的生理现象,所以才“动”起来。

基于GIF这一思路,因此若想要实现上述效果,大致思路为:拆帧-处理-合帧。具体描述为:

  1. 获取GIF的各个帧的图片
  2. 逐个处理各个帧的图片,如把各个帧的图片处理成灰度字符图
  3. 将步骤2处理后的各帧图片,按照原始次序,再合并为新GIF并输出。

今天我们主要介绍一下第一步,即,如何获取到GIF的各个帧。

涉及的主要库

Python的Image库:Pillow

可以链接查看其各个模块的详细使用文档,如下文使用的Image.open,Image.tell,Image.save,Image.seek。

主要代码

获取各个帧

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
import os
from PIL import Image

def gif2pic(file, childrenDir, childrenPicName):
'''
file: gif 文件
childrenDir: 各个帧的图片输出子文件夹路径,需要带‘/’
childrenPicName: 各个帧的图片名称前缀
'''
# 获取图片
im = Image.open(file)
path = os.getcwd()

# 创建存放各个帧图片的路径
if(not os.path.exists(path+childrenDir)):
os.mkdir(path+childrenDir)
os.chdir(path+childrenDir)
# 清空 tmp 目录下内容
for f in os.listdir(path+childrenDir):
os.remove(f)
try:
while 1:
# 帧号
current = im.tell()
name = file.split('.')[0]+'_' + childrenPicName + '_'+str(current)+'.png'
# 保存图片
im.save(name)
# 下一帧
im.seek(current+1)
except:
os.chdir(path)

## 若按照如下命令执行,则需要图片与程序放置在同一个目录下
gif2pic('caixukun.gif', '/caixukun', 'p')

函数解读

Image.open(fp, mode=’r’, formats=None)

官方文档描述如下:

1
2
3
Opens and identifies the given image file.

This is a lazy operation; this function identifies the file, but the file remains open and the actual image data is not read from the file until you try to process the data (or call the load() method).

大概意思是:打开并标识给定的图片文件,并且是一个惰性操作,标记文件并保持打开状态,直到尝试处理数据时才读取实际的图像数据。

Image.tell()

1
2
3
4
5
6
Returns the current frame number. See seek().

If defined, n_frames refers to the number of available frames.

RETURNS:
Frame number, starting with 0.

翻译过来就是范围当前的帧号,从0开始。

Image.seek(frame)

1
2
3
4
5
6
7
8
9
10
11
Seeks to the given frame in this sequence file. If you seek beyond the end of the sequence, the method raises an EOFError exception. When a sequence file is opened, the library automatically seeks to frame 0.

See tell().

If defined, n_frames refers to the number of available frames.

PARAMETERS:
frame – Frame number, starting at 0.

RAISES:
EOFError – If the call attempts to seek beyond the end of the sequence.

翻译过来,大概意思是查找序列文件中的给定帧,超出序列末尾则会引发异常,如果一个打开一个序列文件,则自动指向第0帧。

python3彩色图片转字符图

发表于 2023-03-09 | 分类于 python |

Python3 彩色图片转字符图

实现的最终效果

我们想要实现的一种如下所示的效果:

输入的原图

happy.jpg

输出的效果图(由字符构成的图)

微信截图_20230201184917.png

我们来看看如何通过Python的PIL库来实现。

具体实现代码

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
from PIL import Image, ImageDraw, ImageFont

# 将图片处理成字符画
def img2ascii(img, outName, ascii_chars, isgray, font, scale):
# 将图片转换为 RGB 模式
im = Image.open(img).convert('RGB')
# 设定处理后的字符画大小
print(im.width)
print(im.height)
raw_width = int(im.width * scale)
raw_height = int(im.height * scale)
# 获取设定的字体的尺寸
font_x, font_y = font.getsize(' ')
# 确定单元的大小
block_x = int(font_x * scale)
block_y = int(font_y * scale)
# 确定长宽各有几个单元
w = int(raw_width/block_x)
h = int(raw_height/block_y)
# 将每个单元缩小为一个像素
im = im.resize((w, h), Image.NEAREST)
# txts 和 colors 分别存储对应块的 ASCII 字符和 RGB 值
txts = []
colors = []
for i in range(h):
line = ''
lineColor = []
for j in range(w):
# 获取RGB的值,pixel格式[R, G, B]
pixel = im.getpixel((j, i))
lineColor.append((pixel[0], pixel[1], pixel[2]))
# 根据该点的RGB值,将其转换成对应的字符
line += get_char(ascii_chars, pixel[0], pixel[1], pixel[2])
txts.append(line)
colors.append(lineColor)
# 创建新画布
img_txt = Image.new('RGB', (raw_width, raw_height), (255, 255, 255))
# 创建 ImageDraw 对象以写入 ASCII
draw = ImageDraw.Draw(img_txt)
for j in range(len(txts)):
for i in range(len(txts[0])):
if isgray:
# 可以去https://www.sioe.cn/yingyong/yanse-rgb-16/ 查一下(119,136,153)是什么颜色的
draw.text((i * block_x, j * block_y), txts[j][i], (119,136,153))
else:
draw.text((i * block_x, j * block_y), txts[j][i], colors[j][i])
img_txt.save(outName)

# 将不同的灰度值映射为 ASCII 字符
def get_char(ascii_chars, r, g, b):
length = len(ascii_chars)
# 对于 sRGB 色彩空间,一种颜色的相对亮度定义为:
# L = 0.2126 * R + 0.7152 * G + 0.0722 * B
gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
# gray在0-255之间,因此gray/256 * length 肯定是介于 [0, length - 1]之间
return ascii_chars[int(gray/(256/length))]

img2ascii('happy.jpg', 'after_happy.jpg', 'MNHQ$OC67+>!:-. ', True, ImageFont.load_default(), 1)

相关库

Python的Image库:Pillow

可以链接查看其各个模块的详细使用文档,该程序使用的主要是以下几个方法Image.open,Image.convert,Image.resize,Image.new,ImageDraw.Draw,image.save。

代码解读

首先通过Image.open读原图,并通过Image.convert将其转换为RGB模式。convert函数支持的具体模式列表可参考官方文档。

官方文档中对于L模式(8-bit pixels, black and white)与RGB模式的转换公式如下:

1
L = R * 299/1000 + G * 587/1000 + B * 114/1000

所以,如果我们不采用sRGB也可以尝试一下通过这种方式来将RGB转换为亮度,即上文代码中的get_char函数中的gray的计算方式。

获取图片后,紧接着获取图片的宽高,并根据scale值计算处理后图的宽高,并原图按照处理后的宽高进行缩放,即resize,第二个参数为缩放过程的取样方式,Image.NEAREST即取距离最近的像素而忽略其他的输入像素,其他可取的值还有Image.BOX等等,具体可以参考文档。

然后通过txts存储像素转换之后的字符,colors存储像素转换后的颜色。

最终,通过ImageDraw逐个字符的写入并保存。

python3多张图片拼接成GIF

发表于 2023-03-09 | 分类于 python |

Python3 多帧图片拼接成GIF

在python3如何处理GIF图片中,我们介绍了如何通过python的PIL库,使用Image.open,Image.tell,Image.save,Image.seek四个函数,将一个GIF拆分成多帧图片的实现方式。本文将介绍如何通过PIL库将多帧图片合成一个GIF图片。

预期实现效果

输入的多张图

image.png

合成的GIF

c3.gif

c5.gif

Pillow库

Pillow库中Image.save函数可以保存多帧图片为gif。

其具体格式为:

Image.save(fp, format=None, **params)

官方的英文文档就不贴了,翻译过来大概是如下含义

将此图像保存在给定的文件名下。如果没有指定格式,则使用的格式由文件名扩展名决定。

关键字选项可用于向作者提供额外的说明。如果写入器没有识别到一个选项,它就会被无声地忽略。每个写入器的图像格式文档中都描述了可用的选项。

您可以使用文件对象而不是文件名。在这种情况下,必须始终指定格式。文件对象必须实现seek、tell和write方法,并以二进制模式打开。

save函数中的**params参数

该参数根据不同的格式有不同的可选项目,具体需要在文档中查看,文档中GIF的部分参数如下截图所示。

image.png

实现思路

根据文档,我们需要按照一定的次序读取图片,并通过append_images参数传递给Image.save函数。

实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from PIL import Image
import os

def pic2gifV2(dir_name, out_name, duration):
'''
dir_name: 存放各个帧的图片目录
out_name: 输出的文件名
duration: gif的播放速度
'''
path = os.getcwd()
os.chdir(dir_name)
dirs = os.listdir()
images = []
# 获取图片大小
firstImage = Image.open(dirs[0])
for d in dirs:
images.append(Image.open(d))
img = Image.new('RGB', (firstImage.width, firstImage.height), (255, 255, 255))
img.save(path + '/' + out_name + '.gif', save_all=True, append_images=images[1:], duration=duration)


pic2gifV2('caixukun/', 'c5', 100)

除了使用Pillow库,也可以使用imageio来实现,主要代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import imageio
import os

def pic2gif(dir_name, out_name, duration):
path = os.getcwd()
os.chdir(dir_name)
dirs = os.listdir()
images = []
num = 0
for d in dirs:
images.append(imageio.imread(d))
num += 1
os.chdir(path)
imageio.mimsave(out_name + '.gif',images,duration = duration)

陈皓-我做系统架构的一些原则-笔记

发表于 2021-12-31 |

原文链接:https://coolshell.cn/articles/21672.html

阅读全文 »

何时应该使用parrallelStream

发表于 2021-05-22 |

非专业翻译,欢迎指正!

——————————-原文翻译————————————-

原文链接:http://gee.cs.oswego.edu/dl/html/StreamParallelGuidance.html

辅助翻译工具:DeepL

阅读全文 »

使用keep-alive保存滚动条的位置

发表于 2020-10-17 |

一种是通过vue-router/activated保存和恢复组件的整体滚动条位置,一种是通过deactivated/activated保存组件内部某个组件的滚动条位置

阅读全文 »

VUE快速上手

发表于 2020-04-10 |

vue基本知识

阅读全文 »
12…8
Kiwi

Kiwi

78 日志
20 分类
15 标签
GitHub E-Mail
© 2023 Kiwi
由 Hexo 强力驱动
|
主题 — NexT.Gemini v5.1.4
本站总访问量次 有人看过我的博客啦
冀ICP备18034425号-1