masalibの日記

システム開発、運用と猫の写真ブログです

【python3】pythonのPillowで画像の圧縮して、はてなフォトに投稿する

前回、画像の圧縮ができたので圧縮した画像をはてなフォトに投稿したいと思います

仕様

動き

  1. urlから画像をダウンロードして圧縮する
  2. ダウンロードした画像の縦横のピクセルを取得する
  3. 変換した画像サイズのピクセル数を計算する
  4. 画像圧縮する
  5. 変換画像を保存する
  6. はてなフォトの投稿用のXMLを作成する
  7. はてなAPIの認証用のヘッダーを作成する
  8. はてなフォトAPIにPOST送信する
  9. 結果のXMLを取得する

ソース

from base64 import b64encode
from datetime import datetime
from hashlib import sha1
import random
import requests
import sys
from pathlib import Path
import IPython
from io import StringIO
import io
import urllib.request
from PIL import Image

now = datetime.now()
dtime = str(now.year)+"""-"""+str(now.month)+"""-"""+str(now.day)+"""T"""+str(now.hour)+""":"""+str(now.minute)+""":"""+str(now.second)
print (dtime)
hatena_id = "masalib"
password = "xxxxxx"

username = hatena_id
api_key  = password 


# はてな送信用のヘッダーに認証データ
def wsse(username: str, api_key: str) ->str:
    created = datetime.now().isoformat() + "Z"
    b_nonce = sha1(str(random.random()).encode()).digest()
    b_digest = sha1(b_nonce + created.encode() + api_key.encode()).digest()
    return f'UsernameToken Username="{username}", PasswordDigest="{b64encode(b_digest).decode()}", Nonce="{b64encode(b_nonce).decode()}", Created="{created}"'

# はてなフォトに送るためのXMLデータ作成
def create_photo_data(file_name: str,title : str) ->str:
    uploadData = b64encode(Path(file_name).read_bytes())
    return """
    <entry pxmlns="http://purl.org/atom/ns#">
    <title>""" + title + """</title>
    <content mode="base64" type="image/jpeg">""" + uploadData.decode() + """</content>
    </entry>
    """


def post_hatena_photo_api(data):
    headers = {'X-WSSE': wsse(username, api_key)}
    url = 'http://f.hatena.ne.jp/atom/post/'
    r = requests.post(url, data=data, headers=headers)
    print(r.status_code)
    xml_data =r.text
    return xml_data

# 画像のURLからデータを取得してリサイズする
def get_imagedata_resize(url :str):
    f = io.BytesIO(urllib.request.urlopen(url).read())
    img = Image.open(f)
    before_x, before_y = img.size[0], img.size[1]
    # 横基軸の場合
    width = 480
    x = width
    y = int(round(float(width / float(before_x) * float(before_y))))

    img = img.resize((x,y), Image.LANCZOS)
    return img

savefilepath="resized" + dtime + ".jpg"
title="resizetitle"

imagesrc ="https://cdn-ak.f.st-hatena.com/images/fotolife/m/masalib/20190311/20190311221952.jpg"
imgdata = get_imagedata_resize(imagesrc)
imgdata.save(savefilepath)

print("data作成")

data = create_photo_data(savefilepath,title)

#print("はてなフォトに送信")
hatena_photo_post_xml = post_hatena_photo_api(data)
print(hatena_photo_post_xml)

#IPython.display.Image(savefilepath)

結果

XMLが表示されているだけですがよかったwww

感想

先人の知恵に感謝です。自分の力のみでは作れなかった

teratail.com