python3生成自定义大小的图片

现可生成几kb到几个G大小的图片,格式有png和jpg

图片的编码是瞎拼接的,图片可正常打开预览,用于偶尔测试图片上传接口的功能,菜鸡一枚,路过大佬多多指教!
623—更新了一下

# -*- coding:utf-8 -*-
import os
import time
import binascii
import sys
import datetime
import cv2
from PIL import Image, ImageFont, ImageDraw
import shutil
import pyttsx3
from moviepy.editor import *
import random
from docx import Document
from docx.shared import Inches
import openpyxl

# 获取当前路径
current_path = os.path.dirname(os.path.abspath(__file__))


def file_path_all():
    filepath = "C:/Users/" + getusername() + "/Desktop/" + "new_file/"
    if not os.path.exists(filepath):
        os.makedirs(filepath)
    return filepath


# 获取当前系统username, 如chinaren
def getusername():
    namelist = os.popen("echo %username%").readlines()
    username = namelist[0].replace("\n", "")
    return username


# 获取时间和日期
def getnowdatatime(flag=0):
    """
    flag = 0为时间和日期         eg:2018-04-11 10:04:55
    flag = 1仅获取日期           eg:2018-04-11
    flag = 2仅获取时间           eg:10:04:55
    flag = 3纯数字的日期和时间   eg:20180411100455
    """
    now = time.localtime(time.time())
    if flag == 0:
        return time.strftime("%Y-%m-%d %H:%M:%S", now)
    if flag == 1:
        return time.strftime("%Y-%m-%d", now)
    if flag == 2:
        return time.strftime("%H:%M:%S", now)
    if flag == 3:
        return time.strftime("%Y%m%d%H%M%S", now)


def generate_char(char_num):
    character_str = ""
    for i in range(char_num):
        start, end = 0x4E00, 0x9FA5  # 中文字符的Unicode编码范围
        char_code = random.randint(start, end)  # 随机生成中文字符的Unicode编码
        char = chr(char_code)  # 将Unicode编码转换成中文字符
        character_str = character_str + char
    return character_str


def make_picture(file_path, picture_num, image_width=1280, image_height=720):
    for i in range(picture_num):
        time_text = datetime.datetime.now().strftime("%Y%m%d%H%M%S%f")
        picture_txt = generate_char(10)
        color_tuple = ()
        for i in range(3):
            new_value = random.randint(0, 255)
            color_tuple = color_tuple + (new_value,)
        image = Image.new("RGB", (image_width, image_height), color_tuple)  # 设置画布大小及背景色
        font = ImageFont.truetype(
            font="%s/configfile/华文行楷.TTF" % current_path,
            size=int(image_width * 0.11),
        )  # 设置字体及字号
        draw = ImageDraw.Draw(image)
        # fwidth, fheight = draw.textsize(time_text, font) # 获取文字高宽
        draw.text((10, image_height / 2), picture_txt, "black", font)
        save_picture_path = file_path + time_text + ".jpg"
        image.save(save_picture_path)  # 保存图片
        # return save_picture_path


def circle_print():
    list_circle = ["😂😘🤩😊", "🤩😊💕🥰", "🥰😊😘🤣", "😂🥰😘😊"]
    print("\r{}".format(list_circle[random.randint(1, 4) % 4]), end="", flush=True)


def ready_start(new_file_type, child_level=None):
    file_path_name = (
        new_file_type + datetime.datetime.now().strftime("%Y%m%d%H%M%S") + "/"
    )
    docx_file_path = file_path_all() + file_path_name
    os.makedirs(docx_file_path)  # 创建文件目录
    if child_level:
        docx_file_path_picture = docx_file_path + child_level + "/"
        os.makedirs(docx_file_path_picture)


class MakeWordFile:
    def __init__(self) -> None:
        file_path_name = "doc" + datetime.datetime.now().strftime("%Y%m%d%H%M%S") + "/"
        self.docx_file_path = file_path_all() + file_path_name
        self.docx_file_path_picture = self.docx_file_path + "picture/"
        os.makedirs(self.docx_file_path)  # 创建文件目录
        os.makedirs(self.docx_file_path_picture)
        self.word_type = "docx"
        self.doc_size = float(input("输入文档大小(单位M,实际略略小一丢丢,1M内随机略一丢丢):"))
        self.word_type_input = input("默认回车类型 docx,doc扣 doc:")
        if self.word_type_input:
            self.word_type = self.word_type_input

    def add_doc_content(self):
        doc_name = (
            self.docx_file_path
            + datetime.datetime.now().strftime("%Y%m%d%H%M%S")
            + "."
            + self.word_type
        )
        document = Document()
        document.save(doc_name)
        make_picture(self.docx_file_path_picture, 100)
        print("稍等生成中!")
        while True:
            picture_file_path = self.docx_file_path_picture + random.choice(
                os.listdir(self.docx_file_path_picture)
            )
            file_size = os.path.getsize(picture_file_path)
            now_doc_size = os.path.getsize(doc_name)
            if (self.doc_size * 1024 * 1024 - now_doc_size) <= file_size:
                break
            else:
                # 添加段落、图片
                document.add_paragraph(generate_char(5000))
                document.add_picture(picture_file_path, width=Inches(6))
                document.save(doc_name)
            circle_print()
        doc_lack_size = int(self.doc_size * 1024 * 1024 - os.path.getsize(doc_name))
        document.add_paragraph("1" * doc_lack_size)
        document.save(doc_name)
        print("完成!文件:", doc_name)


class MakeExcelFile:
    def __init__(self) -> None:
        file_path_name = (
            "Excel" + datetime.datetime.now().strftime("%Y%m%d%H%M%S") + "/"
        )
        self.docx_file_path = file_path_all() + file_path_name  # ExcelDemoFile.xlsx
        os.makedirs(self.docx_file_path)  # 创建文件目录
        self.excel_file_size = float(input("Excel大小(单位M):"))
        excel_file_type = int(input("xlsx:1,xls:2:"))
        if excel_file_type == 1:
            self.demo_file = self.docx_file_path + "ExcelDemoFile.xlsx"
            shutil.copy("make_file/configfile/ExcelDemoFile.xlsx", self.docx_file_path)
        else:
            print("此路不通!待续")
            sys.exit(0)
            # self.demo_file = self.docx_file_path + 'ExcelDemoFile.xls'
            # # 打开xlsx文件
            # workbook_xlsx = openpyxl.load_workbook('make_file/configfile/ExcelDemoFile.xlsx')
            # # 保存为xls文件
            # workbook_xlsx.save(self.demo_file)

    def operate_excel_file(self):
        text_content = generate_char(1000)  # 每次插入字节数据 x2
        workbook = openpyxl.load_workbook(self.demo_file)
        while True:
            workbook = openpyxl.load_workbook(self.demo_file)
            file_size = os.path.getsize(self.demo_file)
            if (self.excel_file_size * 1024 * 1024 - file_size) > 3000:
                worksheet = workbook["Sheet1"]
                num_columns = worksheet.max_column  # 获取工作表的列数
                last_row = worksheet.max_row  # 获取最后一行的行号
                for i in range(1, num_columns + 1):
                    worksheet.cell(row=last_row + 1, column=i).value = text_content
            else:
                break
            workbook.save(self.demo_file)
            circle_print()
        print("完成,文件:", self.demo_file)


class MakePDFFile:
    def __init__(self) -> None:
        ready_start(new_file_type="PDFfile")


class MakeFile:
    # 生成指定大小的TXT档
    def generateTXTFile(self):
        fileSize = 0
        file_cell = input("输入文件大小单位(g、m、k):")
        while True:
            size = int(input("请输入生成的文件大小:"))
            if not isinstance(size, int):
                print("只能输入整数,请重新输入!")
                continue
            else:
                fileSize = int(size)
            break
        if file_cell and fileSize:
            if file_cell == "g":
                fileSize = size * 1024 * 1024
            elif file_cell == "m":
                fileSize = size * 1024
            elif file_cell == "k":
                fileSize = size
            else:
                print("文件单位输入不正确!", fileSize)
        if int(fileSize) >= 200:
            print("正在生成TXT文件,请稍候... ...")
        # 生成指定大小的TXT档,修改后缀生成doc、xlsx
        filename = getnowdatatime(3) + "_" + str(fileSize) + "KB.txt"
        print(f"文件名:{filename}")
        doc_file_path = file_path_all()
        f = open(doc_file_path + filename, "w")
        print("文件大小:", (fileSize))
        for i in range(int(fileSize)):
            if i >= 100:
                if i % 100 == 0:
                    print(f"已生成{i//100 * 100}MB数据.")
            try:
                f.write("01" * 512)
            except KeyboardInterrupt:
                print("\n异常中断:KeyboardInterrupt")
                f.close()
                exit(-1)
        f.close()
        print(f"注意!保存路径: {doc_file_path + filename}")


class MakePictures:
    # 生成图片demo
    def create_picture(self, picture_type, time_text, dome_path):
        img = Image.new(mode="RGB", size=(200, 200), color=(17, 178, 208))
        draw = ImageDraw.Draw(img)
        draw.text(xy=(50, 100), text=time_text, fill="red")
        img_name = dome_path + time_text + picture_type
        img.save(img_name)
        return img_name

    def make_picture(self, payload, filepath):
        # filepath为存储的图片的全路径
        # payload为十六进制字符串,将图片源码写入文件
        with open(filepath, "ab") as file_png:
            file_png.write(binascii.a2b_hex(payload.encode()))
        return filepath

    def get_file_size(self, final_file_size, file_size):
        if final_file_size == file_size:
            return 0
        elif file_size < final_file_size:
            return final_file_size - file_size

    def start_run(self):
        picture_type = input("jpg扣1,png直接回车(或直接输入后缀 如:jpeg):")
        final_file_size = input("请输入需生成图片大小(如:1G,1M,1k,无单位则默认为M,拒绝小数!!!):")
        if final_file_size[-1] == "m" or final_file_size[-1] == "M":
            final_file_size = int(final_file_size[:-1]) * 1024 * 1024
        elif final_file_size[-1] == "k" or final_file_size[-1] == "K":
            final_file_size = int(final_file_size[:-1]) * 1024
        elif final_file_size[-1] == "g" or final_file_size[-1] == "G":
            final_file_size = int(final_file_size[:-1]) * 1024 * 1024 * 1024
        else:
            final_file_size = int(final_file_size) * 1024 * 1024
        if picture_type == "1":
            picture_suffix = ".jpg"
        elif picture_type and picture_type != 1:
            picture_suffix = "." + picture_type
        else:
            picture_suffix = ".png"

        time_text = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time()))
        save_tupian_path = file_path_all()
        file_path = save_tupian_path + time_text + picture_suffix
        byte_data = (
            open(self.create_picture(picture_suffix, time_text, save_tupian_path), "rb")
            .read()
            .hex()
        )  # 获取图片的16进制编码
        file_size_txt = sys.getsizeof(byte_data)  # 查看变量所占字节的大小
        while True:
            file_size = os.path.getsize(file_path)
            lack_data_a = self.get_file_size(final_file_size, file_size)  # 已生成图片与目标大小差
            per = file_size / final_file_size * 100  # 百分比进度条
            print("\r图片生成中: %s %.f%s " % ("-" * int(per), per, "%"), flush=True, end="")
            if lack_data_a > file_size_txt:
                self.make_picture(
                    lack_data_a // file_size_txt * byte_data, file_path
                )  # 生成图片
            elif 100 < lack_data_a < file_size_txt:
                self.make_picture("ae426082ae426082ae426082", file_path)
            elif 0 < lack_data_a <= 100:
                self.make_picture("00", file_path)
            elif lack_data_a == 0:
                print("\n完成!!!", file_path)
                break


class MakeVideo:
    def make_video(self, tupian_path, shipin_path, file_width, file_height, video_type):
        file_list = []
        for root, dirs, files in os.walk(tupian_path):
            for file in files:
                file_list.append(file)  # 获取目录下文件名列表
        # VideoWriter是cv2库提供的视频保存方法,将合成的视频保存到该路径中
        time_text = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
        video_file_path = shipin_path + time_text + video_type
        if video_type == ".mp4":
            fourcc = cv2.VideoWriter_fourcc(*"mp4v")
        elif video_type == ".avi":
            print("此路不通!待续")
            sys.exit(0)
            # fourcc = cv2.VideoWriter_fourcc(*'XVID')
        # fourcc = cv2.VideoWriter_fourcc(*'MJPG')  # 'MJPG'意思是支持jpg格式图片
        video = cv2.VideoWriter(
            video_file_path, fourcc, 10, (file_width, file_height)
        )  # 10 视频帧率,分辨率,图片需一致
        for i in range(1, len(file_list)):
            img = cv2.imread(tupian_path + file_list[i - 1])  # 读取图片
            img = cv2.resize(img, (file_width, file_height))  # resize更改像素大小的方法
            video.write(img)  # 写入视频
        video.release()  # 释放资源
        return video_file_path

    def make_picture(self, file_path, image_width=1280, image_height=720):
        for i in range(200):
            time_text = datetime.datetime.now().strftime("%Y%m%d%H%M%S%f")
            color_tuple = ()
            for i in range(3):
                new_value = random.randint(0, 255)
                color_tuple = color_tuple + (new_value,)
            image = Image.new(
                "RGB", (image_width, image_height), color_tuple
            )  # 设置画布大小及背景色
            font = ImageFont.truetype(
                font="%s/configfile/华文行楷.TTF" %current_path,
                size=int(image_width * 0.11),
            )  # 设置字体及字号
            draw = ImageDraw.Draw(image)
            # fwidth, fheight = draw.textsize(time_text, font) # 获取文字高宽
            draw.text((10, image_height / 2), time_text, "black", font)
            image.save(file_path + time_text + ".jpg")  # 保存图片

    def make_audio(self, audio_path):
        audio_path = audio_path + "测试音频.mp3"
        character_str = ""
        for i in range(200):
            start, end = 0x4E00, 0x9FA5  # 中文字符的Unicode编码范围
            char_code = random.randint(start, end)  # 随机生成中文字符的Unicode编码
            char = chr(char_code)  # 将Unicode编码转换成中文字符
            character_str = character_str + char
        pp = pyttsx3.init()
        pp.save_to_file(character_str, audio_path)
        pp.runAndWait()
        return audio_path

    def merge_audio_video(self, mp4_file, mp3_file, result_path, video_type):
        time_text = datetime.datetime.now().strftime("%Y%m%d%H%M%S%f")[:-4]  # 年月日年时分秒毫秒
        video_file_path = result_path + time_text + video_type
        clip_video = VideoFileClip(mp4_file)
        video_time = clip_video.duration  # 获取视频时长
        clip_video.close()
        clip_audio = AudioFileClip(mp3_file)
        audio_time = clip_audio.duration  # 获取音频时长
        clip_audio.close()
        video_clip = VideoFileClip(mp4_file)
        audio_clip = AudioFileClip(mp3_file)
        if video_time > audio_time:
            # 调整视频文件和音频文件的时长一致
            file_clip = video_clip.subclip(audio_clip.start, audio_clip.end)
        else:
            file_clip = audio_clip.subclip(video_clip.start, video_clip.end)
        video_merge = video_clip.set_audio(file_clip)
        video_merge.write_videofile(filename=video_file_path, bitrate="1000k", fps=10)
        return video_file_path

    def splicing_video(
        self,
        data_path,
        video_type,
        video_size=None,
        video_time_need=0,
        make_file_type=0,
    ):
        def operation_video(data_path, save_path):
            file_names = []
            for root, dirs, files in os.walk(data_path):
                for file in files:
                    video = VideoFileClip(os.path.join(root, file))  # 载入视频
                    file_names.append(video)  # 添加到数组
            clip = concatenate_videoclips(file_names)  # 拼接视频
            # 生成目标视频文件, 修改fps
            clip.to_videofile(save_path, fps=10, remove_temp=True, bitrate="1000k")

        del_file = []
        while True:
            time_text = datetime.datetime.now().strftime("%Y%m%d%H%M%S")  # [:-4]
            save_path = data_path + time_text + "视频" + video_type
            operation_video(data_path, save_path)
            del_file.append(save_path)  # 新生成视频路径存放
            if len(del_file) > 1:
                os.remove(del_file[0])  # 删除上一次生成的视频
                del_file.pop(0)

            if make_file_type == 0:
                clip_video = VideoFileClip(save_path)
                video_time = clip_video.duration  # 获取视频时长
                clip_video.close()
                if video_time > video_time_need:
                    break
            elif make_file_type == 1:
                if os.path.getsize(save_path) / 1024 > video_size:
                    break

    def prepare_make(
        self,
        file_width,
        file_height,
        video_type,
        video_size=0,
        video_time_need=0,
        make_file_type=0,
    ):
        new_file = datetime.datetime.now().strftime("%Y%m%d%H%M%S") + "/"
        desktop_path = file_path_all() + new_file
        tupian_path = desktop_path + "tupian_file/"
        audio_path = desktop_path + "yinpin_file/"
        shipin_path = desktop_path + "shipin_file/"
        self.remove_file(tupian_path, audio_path)  # 清理上次文件
        os.makedirs(tupian_path)  # 创建文件目录
        os.makedirs(audio_path)
        os.makedirs(shipin_path)
        self.make_picture(tupian_path, file_width, file_height)
        audio_file = self.make_audio(audio_path)
        video_file_path = self.make_video(
            tupian_path, shipin_path, file_width, file_height, video_type
        )
        self.merge_audio_video(
            video_file_path, audio_file, shipin_path, video_type
        )  # 为视频添加音频
        self.remove_file(video_file_path)
        # self.splicing_video(data_path=shipin_path, video_size=video_size)
        self.splicing_video(
            data_path=shipin_path,
            video_size=video_size,
            video_time_need=video_time_need,
            make_file_type=make_file_type,
            video_type=video_type,
        )

    def remove_file(self, *file_path):
        for i in list(file_path):
            if os.path.isdir(i):
                shutil.rmtree(str(i))  # 删除目录
            elif os.path.isfile(i):
                os.remove(i)  # 删除文件

    def run_make(self):
        video_size_about = 10240  # 目标视频大小,单位k,实际略大500k左右
        file_width, file_height = 1280, 720
        make_file_type = int(input("按时长:0,按大小:1:"))
        video_type = int(input("视频格式:MP4:1,avi:2,其他:3:"))
        if video_type == 1:
            video_type = ".mp4"
        elif video_type == 2:
            video_type = ".avi"
        else:
            print("此路不通!待续")
            sys.exit(0)
        if make_file_type == 1:
            print("依次输入视频文件大小(单位M 正整数,目前最终文件有误差1m左右后面再整)、视频宽和高(例1280, 720)")
            input_str = input("请输入,以英文逗号分隔(例10,1280,720):")
            video_size_about, file_width, file_height = map(str, input_str.split(","))
            self.prepare_make(
                video_size=int(video_size_about) * 1024,
                file_width=int(file_width),
                file_height=int(file_height),
                make_file_type=1,
                video_type=video_type,
            )
        elif make_file_type == 0:
            video_time_need = int(input("输入时长(秒,目前有误差好几秒后面再整):"))
            self.prepare_make(
                file_width=int(file_width),
                file_height=int(file_height),
                video_time_need=video_time_need,
                make_file_type=0,
                video_type=video_type,
            )


if __name__ == "__main__":
    file_type = int(input("文件类型(txt:1、图片:2、视频:3、Word文档:4、Excel文件:5:"))
    if file_type == 1:
        MakeFile().generateTXTFile()  # 文件
    elif file_type == 2:
        MakePictures().start_run()  # 图片
    elif file_type == 3:
        MakeVideo().run_make()  # 视频
    elif file_type == 4:
        MakeWordFile().add_doc_content()  # word文档
    elif file_type == 5:
        MakeExcelFile().operate_excel_file()  # excel文件
    else:
        print("❌")

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值