用python把视频变成字符样式

我们将这样的视频
在这里插入图片描述
变成这个样子
在这里插入图片描述
变得又难看,又看不清,搞这干啥?
闲的咯,下面我们来看看是如何实现的

1、思路

我参考了网上很多人的实现方法,最终我的思路是这样的
1、我们先准备好一个视频,想办法把这个视频变成很多很多的图片
2、接着我们把每一张图片都变成字符串的样式(是把彩色图片变成字符串填充的图片,不是变成一堆字符串)
3、最后,再把转换好的图片变成一个视频
下面我们看看每一步如何利用python实现呢

第一步:视频->图片

嘿嘿,要是一张一张去截图,好像可以满足我们的需求哦,但那肯定不行,我们知道视频都是又一幅幅图片构成的,或者叫一帧一帧的图片构成的,那么在所有的帧中有的帧是关键帧,按道理似乎只要知道关键帧,就可以把前面和后面的图片推导出来,以此似乎可以起到压缩视频的目的,这次我们不管那么多,直接把视频一帧一帧全部保存为图片,不管是不是关键帧。利用opencv-python,实现如下(截取)

    def getFrame(self,videoPath, svPath):
        cap = cv2.VideoCapture(videoPath)
        numFrame = 0
        nums = 0
        while True:
            nums +=1
            if cap.grab():
                flag, frame = cap.retrieve()
                if not flag:
                    continue
                else:
                    numFrame += 1
                    newPath = svPath + str(numFrame) + ".jpg"
                    cv2.imencode('.jpg', frame)[1].tofile(newPath)
            if nums >= self.g_frame_num:
                break
            if cv2.waitKey(10) == 27:
                break 

看到在while循环中,我们视频的帧全部保存下来为jpg图片,g_frame_num是一个类成员变量,可以让我们定取多少帧数据,以此,我们完成第一步

第二步:彩色图片->字符串图片

这部分稍微麻烦一点点,我的思路是这样的,将图片的每个像素点,都用同样色彩的字符代替,然后生成一幅新图片,但是注意,一个字符串占得像素点可不是一个,所以在转换时我们还需要进行一些处理,看看图片应该用多少个像素来填充

ascii_char = list("$@B%8&WM#*oahkbdpqwmZO0QLCJUYXzcvunxrjft/\|()1{}[]?-_+~<>i!lI;:,\"^`'. ")
def get_char(r,g,b,alpha = 256):#获取对应的字符
    if alpha == 0:
        return ' '
    length = len(ascii_char)
    gray = int(0.2126 * r + 0.7152 * g + 0.0722 * b)
    unit = (256.0 + 1)/length
    return ascii_char[int(gray/unit)]
def image_to_strimage(self,isgray=False):
      for k in range(1, self.g_frame_num+1):
          path = './img/' + str(k) + '.jpg'
          im = Image.open(path).convert('RGB')
          raw_width = int(im.width)
          raw_height = int(im.height)
          font = ImageFont.truetype('consola.ttf', 10, encoding='unic')
          font_x, font_y = font.getsize(' ')
          block_x = int(font_x)
          block_y = int(font_y)
          w = int(raw_width / block_x)
          h = int(raw_height / block_y)
          im = im.resize((w, h), Image.NEAREST)
          txts = []
          colors = []
          for i in range(h):  # 遍历行
              line = ''
              lineColor = []
              for j in range(w):  # 遍历列
                  pixel = im.getpixel((j, i))
                  lineColor.append((pixel[0], pixel[1], pixel[2]))
                  line += get_char(pixel[0], pixel[1], pixel[2])
              txts.append(line)
              colors.append(lineColor)
          im_txt = Image.new("RGB", (raw_width, raw_height), (255, 255, 255))
          draw_handle = ImageDraw.Draw(im_txt)
          for j in range(len(txts)):
              for i in range(len(txts[j])):
                  if isgray:
                      draw_handle.text((i * block_x, j * block_y), txts[j][i], (50, 50, 50))
                  else:
                      draw_handle.text((i * block_x, j * block_y), txts[j][i], colors[j][i])
          # name = path + str(k) + '.jpg'
          im_txt.save(path, 'JPEG')
第三步:图片->视频

利用opencv库实现,在循环中顺便吧那些没用的图片删掉(这种方法出来的视频文件较大)

    def show(self):
        img = Image.open('./img/1.jpg')
        w = img.width
        h = img.height
        print('视频格式',w,'*',h)
        videoWriter = cv2.VideoWriter('test.avi', cv2.VideoWriter_fourcc(*'MJPG'), 25, (w, h))
        path_file_number = glob.glob(pathname='./img/*.jpg')
        for i in range(1,len(path_file_number)+1):
            path = './img/' + str(i) + '.jpg'
            img = cv2.imread(path)
            videoWriter.write(img)
            os.remove(path)
        videoWriter.release()
效果大概就是这么个样子

在这里插入图片描述
在这里插入图片描述
没有声音,可以想办法用python去取一下,问题应该不大吧

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值