Python文件基本操作

本文详细介绍了在Python中使用内置函数和第三方库如Pillow和PyMuPDF进行文本文件读取、图片操作,包括逐行读取、内存映射、处理异常以及从URL下载和转换PDF。同时,展示了如何处理大文件和优化内存使用。
摘要由CSDN通过智能技术生成

在Python中,读取 文本文件 一些常见的方法:

  1. 基本文件读取
    使用内置的open函数,可以以只读模式(‘r’)打开文件,并读取其内容。

    with open('filename.txt', 'r') as file:
        content = file.read()
    
  2. 逐行读取
    如果文件内容很大,逐行读取可以更高效地使用内存。

    with open('filename.txt', 'r') as file:
        for line in file:
            print(line.strip())
    
  3. 按行迭代
    Python的文件对象还支持直接迭代,这同样是一种逐行读取的方法。

    with open('filename.txt', 'r') as file:
        for line in file:
            print(line.strip())
    
  4. 读取文件的第一行或几行
    使用file.readline()file.readlines()方法可以读取文件的第一行或所有行。

    with open('filename.txt', 'r') as file:
        first_line = file.readline()
        some_lines = file.readlines()
    
  5. 使用with语句
    with语句是推荐的方式,因为它可以自动关闭文件,即使发生异常也是如此。

    with open('filename.txt', 'r') as file:
        for line in file:
            process(line)
    
  6. 二进制文件读取
    当需要读取非文本文件(如图片或PDF)时,可以使用二进制模式(‘rb’)。

    with open('filename.jpg', 'rb') as file:
        data = file.read()
    
  7. 文件对象的其他方法
    文件对象还提供了readlinebytes()read(size)readinto(buffer)等方法,用于不同的读取需求。

  8. 文件属性
    使用.open()函数打开文件后,可以访问文件的一些属性,如.fileno()获取文件描述符,.isatty()检查文件是否是终端设备等。

  9. 内存映射文件
    对于非常大的文件,可以使用内存映射文件(memory-mapped file)来提高性能。

    import mmap
    with open('filename', 'r') as f:
        m = mmap.mmap(f.fileno(), 0)
        content = m[:]
    
  10. 使用第三方库
    有时,根据特定需求,可能会使用第三方库来读取文件,如pandas读取CSV文件。

    import pandas as pd
    df = pd.read_csv('data.csv')
    
  11. 处理文件编码
    当读取非ASCII文本文件时,可能需要指定编码,如使用UTF-8。

    with open('filename.txt', 'r', encoding='utf-8') as file:
        content = file.read()
    
  12. 错误和异常处理
    在读取文件时,应该考虑异常处理,如处理文件不存在的情况。

    try:
        with open('filename.txt', 'r') as file:
            content = file.read()
    except FileNotFoundError:
        print('文件未找到')
    

每种方法都有其适用场景,选择哪种方式取决于你的具体需求,如文件大小、数据类型、性能要求等。

读取图片

在Python中,读取图片通常使用Pillow库(PIL Fork),以下是使用Pillow读取图片的基本方法:

  1. 安装Pillow
    如果你还没有安装Pillow,可以通过pip安装:

    pip install Pillow
    
  2. 使用Pillow打开图片
    使用Pillow的Image模块来打开图片文件。

    from PIL import Image
    
    # 打开图片文件
    with Image.open('path_to_image.jpg') as img:
        # 显示图片(这将在默认图像查看器中打开图片)
        img.show()
    
        # 或者,你可以获取图片的一些基本信息
        print(img.format, img.size, img.mode)
    
  3. 逐像素读取
    如果你需要对图片的每个像素进行操作,可以像下面这样访问像素数据:

    with Image.open('path_to_image.jpg') as img:
        # 获取图片的宽度和高度
        width, height = img.size
    
        # 遍历图片中的每一个像素
        for x in range(width):
            for y in range(height):
                # 获取当前像素点的颜色值
                pixel = img.getpixel((x, y))
                print(pixel)
    
  4. 转换图片格式
    Pillow也允许你将图片转换为不同的格式:

    with Image.open('path_to_image.jpg') as img:
        # 将图片转换为PNG格式
        img.save('path_to_image.png', 'PNG')
    
  5. 调整图片大小
    使用Pillow,你还可以轻松地调整图片的大小:

    with Image.open('path_to_image.jpg') as img:
        # 调整图片大小为50%原始大小
        new_size = (img.size[0] // 2, img.size[1] // 2)
        img_resized = img.resize(new_size)
        img_resized.save('path_to_resized_image.jpg')
    
  6. 裁剪图片
    Pillow还支持裁剪图片:

    with Image.open('path_to_image.jpg') as img:
        # 裁剪图片的左上角,大小为(100, 100)
        img_cropped = img.crop((0, 0, 100, 100))
        img_cropped.save('path_to_cropped_image.jpg')
    
  7. 旋转图片
    旋转图片也是Pillow支持的一个功能:

    with Image.open('path_to_image.jpg') as img:
        # 旋转图片45度
        img_rotated = img.rotate(45, expand=True)
        img_rotated.save('path_to_rotated_image.jpg')
    
  8. 使用with语句
    与文件操作一样,使用with语句来打开图片可以确保图片在操作完成后正确关闭。

  9. 异常处理
    在读取图片时,也可能遇到文件不存在或格式不支持等问题,因此异常处理也很重要:

    try:
        with Image.open('path_to_image.jpg') as img:
            # 处理图片
            pass
    except IOError as e:
        print('打开图片时出错:', e)
    

Pillow是一个非常强大的库,它提供了丰富的功能来处理图像数据,上述只是一些基本操作。根据你的具体需求,Pillow还支持许多其他高级功能。

使用Pillow 读取图片文件后,如何获取文件的 “file_data”, 上传文件

在使用Pillow读取图片文件后,如果你想要获取图片的字节数据(通常称为file_data),以便上传到对象存储服务(如a里云OSS)时使用,你可以按照以下步骤操作:

  1. 使用Pillow打开图片文件。
  2. 将图片转换为字节数据。

以下是获取图片字节数据的代码示例:

from PIL import Image
import io

# 图片文件路径
image_path = 'path_to_image.jpg'

# 使用Pillow打开图片
with Image.open(image_path) as img:
    # 创建一个字节流来存储图片的字节数据
    img_byte_arr = io.BytesIO()
   
    # 将图片保存到字节流中,指定格式为JPEG或PNG等,取决于你的图片格式
    img.save(img_byte_arr, format='JPEG')
    
    # 获取图片的字节数据
    file_data = img_byte_arr.getvalue()
    
    # 此时file_data包含了图片的字节数据,可以用于上传到OSS等

在上述代码中,我们首先使用Image.open()打开了图片文件。然后,我们创建了一个io.BytesIO对象,这是一个在内存中存储字节数据的流对象。接着,我们调用img.save()方法,并将img_byte_arr作为文件对象传递,同时指定保存的图片格式。这样,图片的字节数据就被写入到img_byte_arr中。

最后,我们调用getvalue()方法来获取字节流中的字节数据,存储在变量file_data中。此时,file_data包含了整个图片的字节数据,可以直接用于上传到OSS。

如果你需要上传到OSS,可以使用OSS的SDK来上传这些字节数据。以下是使用阿里云OSS SDK Python版本的一个简单示例:

import oss2
# 填写你的OSS endpoint,格式为 oss-region.aliyuncs.com
endpoint = 'OSS_ENDPOINT'
# 填写你的OSS AccessKey ID
access_key_id = 'ACCESS_KEY_ID'
# 填写你的OSS AccessKey Secret
access_key_secret = 'ACCESS_KEY_SECRET'
# 创建OSS服务的实例
oss_service = oss2.Service(endpoint, access_key_id, access_key_secret)

# 指定OSS的存储桶名称
bucket_name = 'BUCKET_NAME'
# 获取存储桶对象
bucket = oss_service.get_bucket(bucket_name)

# 指定要上传的文件在OSS上的名称
oss_key = 'TARGET_FILE_NAME.jpg'

# 上传字节数据到OSS
bucket.put_object_from_bytes(file_data, oss_key)

print(f'图片已上传到OSS,文件名: {oss_key}')

请确保你已经安装了oss2库,并且替换了上面代码中的OSS_ENDPOINTACCESS_KEY_IDACCESS_KEY_SECRETBUCKET_NAMETARGET_FILE_NAME.jpg为你自己的OSS信息。

从 URL 下载 pdf 文件,然后使用 fitz.open打开处理

通过HTTP请求从URL下载PDF文件,然后使用PyMuPDF打开这个PDF文件。

  1. res.content是响应的字节流,而不是文件路径。因此,不能直接将其作为fitz.open的参数,因为fitz.open函数期望的是一个文件路径或者一个文件对象。

  2. 需要先将response的字节流写入到一个文件中,或者创建一个文件对象,然后才能用PyMuPDF打开。

import requests
import fitz
import io

ch_url = 'http://example.com/somefile.pdf'

# 使用requests获取PDF文件内容
res = requests.get(ch_url)

if res.status_code == 200:
    # 因为res.content是字节流,我们可以使用io.BytesIO来创建一个文件对象
    pdf_file_obj = io.BytesIO(res.content)
    
    # 使用PyMuPDF打开PDF文件对象
    pdf_document = fitz.open(pdf_file_obj)
    
    # 处理pdf_document,例如读取页面等
    # ...
else:
    print(f"Failed to retrieve PDF, status code: {res.status_code}")

在这个修改后的代码中,我们使用io.BytesIO将字节流转换成一个文件对象。然后,这个文件对象可以被PyMuPDF的fitz.open方法接受,从而打开PDF文件进行进一步的操作。

请注意,如果你确实需要将PDF文件保存到本地磁盘,可以在创建文件对象之前,使用open函数以二进制写入模式将字节流写入到文件中:

# 将PDF字节流写入到本地文件
with open('downloaded_file.pdf', 'wb') as f:
    f.write(res.content)

# 然后使用PyMuPDF打开这个本地文件
pdf_document = fitz.open('downloaded_file.pdf')

确保在运行上述代码时,有足够的权限将文件保存到指定的目录。

pdf to image

使用PyMuPDF将PDF转换成图片,然后使用Pillow库将这些图片从上至下拼接成一张长图,中间生成的图片不需要写入磁盘,步骤:

  1. 使用PyMuPDF读取PDF文件,并获取每一页的图像数据。
  2. 将每一页的图像数据转换为Pillow图像对象。
  3. 使用Pillow库将这些图像对象从上至下拼接成一张长图。
import fitz  # PyMuPDF
from PIL import Image

def pdf_to_vertical_image(pdf_path):
    # 打开PDF文件
    pdf_document = fitz.open(pdf_path)
    
    # 准备一个列表来收集所有的Pillow图像对象
    images = []
    
    # 遍历PDF的每一页
    for page_number in range(len(pdf_document)):
        # 获取页面对象
        page = pdf_document.load_page(page_number)
        
        # 将页面转换为一个Pillow图像对象
        # 这里使用默认的格式和参数,你可以根据需要调整
        pixmap = page.get_pixmap()
        img = Image.frombytes(
            "RGB",
            [pixmap.width, pixmap.height],
            pixmap.samples
        )
        
        # 将图像对象添加到列表中
        images.append(img)
    
    # 关闭PDF文档
    pdf_document.close()
    
    # 使用Pillow将图像列表从上至下拼接成一张长图
    # 这里使用Pillow的内置方法来实现
    # 我们不保存中间的单个页面图像,直接进行拼接
    widths, heights = zip(*(i.size for i in images))
    
    total_width = max(widths)
    max_height = sum(heights)
    
    # 创建一个新图像,用于拼接
    new_im = Image.new('RGB', (total_width, max_height))
    
    y_offset = 0
    for im in images:
        new_im.paste(im, (0, y_offset))
        y_offset += im.size[1]
    
    # 返回拼接后的长图图像对象
    return new_im

# 使用示例
pdf_path = 'example.pdf'  # PDF文件路径
vertical_image = pdf_to_vertical_image(pdf_path)

# 保存或显示结果图片
vertical_image.save('vertical_image.jpg')
vertical_image.show()

这段代码首先定义了一个函数pdf_to_vertical_image,它接受一个PDF文件的路径作为参数。函数使用PyMuPDF打开PDF文件,并遍历每一页,将每一页转换为一个Pillow图像对象,并将这些对象存储在一个列表中。

然后,代码计算出所有图像的宽度和高度,确定拼接后图像的尺寸,并创建一个新的Pillow图像对象作为拼接的目标。

接下来,代码使用一个循环将列表中的每个图像粘贴到新图像的正确位置上,从而实现从上至下的拼接。

最后,函数返回拼接后的长图图像对象,你可以保存或显示这个图像,而不需要将中间的单个页面图像写入磁盘。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值