我們將這樣的視頻
變成這個樣子
變得又難看,又看不清,搞這幹啥?
閒的咯,下面我們來看看是如何實現的
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去取一下,問題應該不大吧