如何用图床服务存储图片?(python)

使用图床服务存储图片的步骤如下:

  1. 选择图床服务提供商
    常见的图床服务有 SM.MS、Imgbb、Postimage 等。选择时可以考虑服务稳定性、免费容量、上传速度等因素。

  2. 获取图床 API 密钥
    大多数图床服务都提供 API 接口,需要先注册账号并获取相应的 API 密钥。这个密钥用于授权应用程序访问图床服务。

  3. 上传图片到图床
    通常可以使用 HTTP POST 请求将图片数据上传到图床服务。可以把图片数据转换为 Base64 编码后上传,或者直接上传二进制数据。

     

    示例代码(使用 Python 和 requests 库):

     
    import requests
    import base64
    
    # 图片数据(Base64 编码)
    image_data = base64.b64encode(open('image.png', 'rb').read())
    
    # 图床 API 密钥
    api_key = 'your_api_key'
    
    # 请求头
    headers = {'Authorization': api_key}
    
    # 上传文件
    files = {'smfile': ('image.png', image_data)}
    url = 'https://sm.ms/api/v2/upload'
    response = requests.post(url, files=files, headers=headers)
    
    # 解析响应
    data = response.json()
    if data['success']:
        image_url = data['data']['url']
        print(f'Image uploaded successfully: {image_url}')
    else:
        print(f'Error uploading image: {data["message"]}')
    
  4. 将图片 URL 保存到数据库
    在应用程序中,将上传成功后返回的图片 URL 保存到数据库中,以便后续使用。

使用图床服务可以避免将图片数据直接存储在数据库中,减轻数据库的负担。同时,图床服务通常提供更好的图片管理和访问功能。不过需要注意的是,需要考虑图床服务的可靠性和长期可用性。

def create(self, value_list):
    for value in value_list:
        value['image_id'] = self.env['ir.sequence'].next_by_code('image')

        # 图床
        image_data = value['image']
        image_data = base64.b64decode(image_data)

        headers = {'Authorization': '???'}

        files = {'smfile': ('image.png', image_data)}
        url = 'https://sm.ms/api/v2/upload'
        res = requests.post(url, files=files, headers=headers).json()
        value['image_path'] = res['data']['url']
        print(res['data']['url'])
        print(value['image_path'])

        # 本地生成图片路径
        # base_path = 'bitpulse/tutor/images'
        # image_data = value['image']
        # timestamp = datetime.datetime.now().strftime('%Y%m%d%H%M%S')
        # file_name = f'{timestamp}.png'
        # file_path = os.path.join(base_path, file_name)
        #
        # # 解码 Base64 编码的字符串为字节数据
        # byte_data = base64.b64decode(image_data)
        #
        # byte_stream = io.BytesIO(byte_data)  # 请求数据转化字节流
        #
        # try:
        #     roi_img = Image.open(byte_stream)  # Image打开二进制流Byte字节流数据
        #     imgByteArr = io.BytesIO()  # 创建一个空的Bytes对象
        #     roi_img.save(imgByteArr, format='PNG')  # PNG就是图片格式
        #     imgByteArr = imgByteArr.getvalue()  # 保存的二进制流
        #
        #     # 生成文件目录
        #     if not os.path.exists(base_path):
        #         os.makedirs(base_path)
        #
        #     # 创建图片
        #     with open(file_path, "wb+") as f:
        #         f.write(imgByteArr)
        #
        #     value['image_path'] = file_path
        #     print(value['image_path'])

        # except IOError:
        #     print("无法识别图像文件")

    return super().create(value_list)

这个 create 方法是用于创建多个图像记录的接口。下面是一些关键点:

  1. 遍历传入的 value_list,对每个值进行处理。
  2. 为每个图像记录生成一个唯一的序列号,使用 Odoo 的 ir.sequence 模块。
  3. 从 value 字典中获取 image 字段的 Base64 编码的图像数据。
  4. 使用 base64.b64decode() 函数将 Base64 编码的数据解码为原始的字节数据。
  5. 将图像数据上传到图床服务(sm.ms)。
    • 使用 requests 库发送 POST 请求,上传图像并获取图像的 URL。
    • 将图像 URL 存储在 image_path 字段中。
  6. 这个接口还包含了注释掉的代码,用于在本地文件系统上存储图像。
    • 根据当前时间戳生成文件名。
    • 使用 Image 模块打开 Base64 编码的图像数据,并将其保存到本地文件系统。
    • 将图像文件路径存储在 image_path 字段中。
  7. 如果出现 IOError 异常,则打印错误信息。
  8. 最后,调用父类的 create() 方法,将处理后的 value_list 创建为新的记录。

这个接口的主要功能是:

  1. 为每个图像记录生成一个唯一的序列号。
  2. 将图像数据上传到图床服务,并将图像 URL 存储在数据库中。
  3. 作为一个批量创建图像记录的接口,调用父类的 create() 方法完成实际的数据库操作。

 使用实例:

一个首页接口的实例

# 首页接口
@http.route(['/home'], type="json", auth="none", methods=['POST'], cors='*', csrf=False)
def get_home(self, **kwargs):
    values = {'success': True, 'code': 200, 'message': '', 'data': ''}
    data = {'address': '', 'image': '', 'announcement': '', 'notice': '', 'academic_news': '', 'message': ''}

    address = []
    title_address = request.env['tutor.title'].sudo().search([('name', '=', '上课区域')])
    addresses = request.env['tutor.title.value'].sudo().search([('title_id', '=', title_address.id)])
    for value in addresses:
        address.append(value.name)

    image_list = request.env['tutor.image'].sudo().search([], order='create_date desc')
    if len(image_list) < 5:
        image = [record.image_path for record in image_list]
    else:
        image = [record.image_path for record in image_list[:5]]

    print(image)
    print('****')

    announcement_list = request.env['tutor.announcement'].sudo().search([], order='create_date desc')
    if len(announcement_list) < 5:
        announcement = [value.content for value in announcement_list]
    else:
        announcement = [value.content for value in announcement_list[:5]]

    notice = []
    notice_list = request.env['tutor.notice'].sudo().search([], order='create_date desc')
    for value in notice_list:
        notice_value = {'id': '', 'name': '', 'is_top': ''}
        notice_value['id'] = value.id
        notice_value['name'] = value.name
        notice_value['is_top'] = value.is_top

        notice.append(notice_value)

    academic_news = []
    academic_list = request.env['tutor.academic.title'].sudo().search([])
    for value in academic_list:
        academic_value = {'id': '', 'name': '', 'title': '', 'image': ''}
        academic_value['id'] = value.id
        academic_value['title'] = value.name
        academic_value['image'] = value.image
        academic_value['name'] = request.env['tutor.academic.kopp'].sudo().search([('titles', 'in', value.id)], limit=1).name
        academic_news.append(academic_value)

    message = []
    message_list = request.env['tutor.message'].sudo().search([('invisible', '=', False), ('approve_message', '=', 'done')], order='create_date desc')
    if len(message_list) < 10:
        messages = [record for record in message_list]
    else:
        messages = [record for record in message_list[:5]]
    for value in messages:
        message_value = {'username': '', 'message': '', 'time': '', 'image': ''}
        customer = request.env['tutor.customer'].sudo().search([('id', '=', value.customer_id.id)])
        message_value['username'] = customer.phone
        message_value['message'] = value.content
        message_value['image'] = value.customer_id.image
        message_value['time'] = value.time.strftime("%Y-%m-%d %H:%M:%S")
        message.append(message_value)

    data.update({'address': address, 'image': image, 'announcement': announcement,
                 'notice': notice, 'academic_news': academic_news, 'message': message})
    values.update({'data': data})
    return values

# 滚轮
@http.route(['/rolling'], type="json", auth="none", methods=['POST'], cors='*', csrf=False)
def rolling(self, **post):
    values = {'success': True, 'code': 200, 'message': '', 'data': ''}
    name = str(post.get('name'))
    page = int(post.get('page', 1))
    per_page = 10
    offset = (page - 1) * per_page
    data = []
    if name == 'notice':
        notice_list = request.env['tutor.notice'].sudo().search([], order='create_date desc')
        page_notice = notice_list[offset:offset + per_page]
        data = [{'id': value.id, 'name': value.name, 'is_top': value.is_top} for value in page_notice]
    else:
        message_list = request.env['tutor.message'].sudo().search([('invisible', '=', False), ], order='create_date desc')
        page_notice = message_list[offset:offset + per_page]
        for value in page_notice:
            customer = request.env['tutor.customer'].sudo().search([('id', '=', value.customer_id.id)])
            data.append({'username': customer.phone, 'time': value.time.strftime("%Y-%m-%d %H:%M:%S"),
                        'message': value.content, 'image': value.customer_id.image})
    values['data'] = data
    return values

这个 Python 代码实现了两个 Odoo 的 HTTP 路由接口,用于获取首页和滚动列表的数据。

  1. Odoo 路由机制

    • Odoo 使用 http.route() 装饰器定义 HTTP 路由,可以指定 URL 路径、请求方法、认证方式等。
    • type="json" 表示该路由返回 JSON 格式的数据。
    • auth="none" 表示该路由不需要用户认证。
    • cors='*' 表示支持跨源资源共享。
    • csrf=False 表示不进行 CSRF 验证。
  2. 数据查询

    • 使用 request.env['model_name'].sudo().search() 查询 Odoo 模型中的数据。
    • sudo() 方法使用管理员权限查询数据。
    • 可以通过条件过滤、排序等参数优化查询结果。
  3. 数据组织和返回

    • 将查询到的数据整理成所需的数据结构,如字典或列表。
    • 将整理好的数据更新到 values 字典中,作为最终返回的 JSON 数据。
  4. 分页处理

    • 在 /rolling 接口中,使用 page 和 per_page 参数实现了分页功能。
    • 通过计算 offset 来获取当前页的数据。
  5. 查询优化

    • 在首页接口中,根据数据长度进行了截取,以限制返回数据的数量。
    • 在滚动列表接口中,也仅返回当前页的数据,减轻了服务器负担。

总的来说,这个代码展示了 Odoo 中使用 HTTP 路由、数据查询、数据组织和返回,以及分页处理的基本知识。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值