一、項目概覽:4 步把照片變成博客

步驟 目標 工具/接口
① 預處理 提取 EXIF、調尺寸、轉 JPG Pillow、piexif
② 地理增強 反向地理編碼 + 附近地標 Google Maps API
③ 視覺描述 圖像→標題 Vertex AI ImageText 模型
④ 故事成文 標題+地理+時間→博客 Vertex AI PaLM + 提示工程

懶人包:直接跑 Colab,改 3 行配置即可生成你的旅行故事。


二、照片預處理:統一格式、瘦身、提坐標

from PIL import Image
import piexif, os, pathlib

SRC_DIR   = "photos"
DST_DIR   = "photos_converted"
MAX_EDGE  = 800          # 最長邊≤800px,減少流量
JPG_QUAL  = 85

pathlib.Path(DST_DIR).mkdir(exist_ok=True)

for img_path in pathlib.Path(SRC_DIR).iterdir():
    img = Image.open(img_path)
    img.thumbnail((MAX_EDGE, MAX_EDGE), Image.LANCZOS)

    # 保存為JPG,復制EXIF
    new_path = pathlib.Path(DST_DIR) / f"{img_path.stem}.jpg"
    exif_dict = piexif.load(img.info.get("exif", b""))
    exif_bytes = piexif.dump(exif_dict)
    img.save(new_path, format="JPEG", quality=JPG_QUAL, exif=exif_bytes)

提取關鍵字段:

from PIL import Image
from PIL.ExifTags import TAGS, GPSTAGS
import datetime, json

def exif_to_decimal(degrees, minutes, seconds, direction):
    deg = degrees[0] / degrees[1]
    min = minutes[0] / minutes[1]
    sec = seconds[0] / seconds[1]
    decimal = deg + min/60 + sec/3600
    return -decimal if direction in ['S', 'W'] else decimal

def get_lat_lng(exif):
    gps = exif.get("GPSInfo")
    if not gps: return None, None
    lat = exif_to_decimal(*gps[2], gps[1])
    lng = exif_to_decimal(*gps[4], gps[3])
    return lat, lng

def extract_meta(img_path):
    img = Image.open(img_path)
    exif = {TAGS.get(k, k): v for k, v in img._getexif().items()}
    lat, lng = get_lat_lng(exif)
    date_str = exif.get("DateTime", "")
    return {"lat": lat, "lng": lng, "date": date_str}

三、Google Maps API 增強:把坐標變地名

import googlemaps, os

MAPS_API_KEY = os.getenv("MAPS_API_KEY")
gmaps = googlemaps.Client(key=MAPS_API_KEY)

def enrich_location(lat, lng, radius=1000):
    if lat is None or lng is None:
        return {"address": None, "nearby": []}
    address = gmaps.reverse_geocode((lat, lng), language="en")[0]["formatted_address"]
    nearby  = gmaps.places_nearby(location=(lat, lng), radius=radius, language="en")["results"][:3]
    return {"address": address, "nearby": [{"name": p["name"], "type": p.get("types", [])] for p in nearby]}

四、Vertex AI:圖像→標題→故事

1. 初始化模型

import vertexai
from vertexai.vision_models import ImageTextModel, Image

PROJECT_ID = "your-gcp-project"
vertexai.init(project=PROJECT_ID)
model = ImageTextModel.from_pretrained("imagetext")

2. 生成標題

def caption_image(img_path):
    img = Image.load_from_file(img_path)
    captions = model.get_captions(
        image=img,
        number_of_results=1,
        language="en"
    )
    return captions[0] if captions else "A memorable moment"

3. 提示模板(Few-Shot)

album_context = """I flew to Los Angeles for a short trip,
and the album contains the photos from the day I arrived there.
The man in those photos is myself."""

few_shot_example = """
Photo 1: Sunset at Santa Monica Pier
Photo 2: Street food on Venice Beach
Blog:
?? Santa Monica, CA — Day 1
I landed in LA just in time for golden hour. The pier stretched into the Pacific, carnival lights flickering...
(insert Photo 1 here)
After sunset, I wandered to Venice Beach for the legendary tacos...
(insert Photo 2 here)
"""

prompt_template = f"""
{album_context}
{few_shot_example}
Now generate a blog post in the same style for the following photos:
{{photos_info}}
"""

4. 調用 PaLM 生成正文

from vertexai.language_models import TextGenerationModel

palm = TextGenerationModel.from_pretrained("text-bison@001")
response = palm.predict(prompt=prompt_template, max_output_tokens=1024)
blog_md = response.text

五、完整 Colab 調用示例

# 1?? 批量處理相冊
meta_list = [extract_meta(p) for p in Path("photos_converted").glob("*.jpg")]

# 2?? 增強地理信息
for m in meta_list:
    m.update(enrich_location(m["lat"], m["lng"]))

# 3?? 生成標題
for m in meta_list:
    m["caption"] = caption_image(m["path"])

# 4?? 組裝 Few-Shot Prompt
photos_info = "\n".join([f"Photo {i+1}: {m['caption']} ({m['address']})"
                         for i, m in enumerate(meta_list)])
final_prompt = prompt_template.format(photos_info=photos_info)

# 5?? 生成博客
blog_md = palm.predict(final_prompt, max_output_tokens=2048).text

六、提示工程小技巧

技術 作用 示例
Few-Shot 減少“跑題” 提供 1-2 段輸出樣板
角色扮演 統一口吻 “你是一名旅行博主”
占位符 方便后期替換 (Photo 1 here) → 正則替換為 ![Photo 1](path)

想系統優化 Prompt?用 代碼審查助手 掃描模板,AI 會提示“缺少輸出長度限制”或“示例與真實字段不一致”等潛在坑。??


七、性能與成本優化

  1. 圖片緩存:先上傳 Cloud Storage,返回公共 URL,避免重復 Base64
  2. Token 復用:Maps 反向地理編碼結果緩存 24 h,節省 \$0.005/次
  3. 并發生成:使用 ThreadPoolExecutor 批量調用 ImageText,10 張照片 <15 秒
  4. PaLM 輸出緩存:相同上下文+標題組合 MD5 做 Key,命中緩存直接返回,節省 50% 費用

緩存策略寫不好?對 代碼優化 說“為 Maps 反向地理編碼加 LRU 緩存”,秒出帶 TTL 的 Python 裝飾器。?


八、一鍵部署與監控

監控指標想量化?用 開發任務管理系統 KPI 輸入“平均生成耗時 ≤ 20 秒,緩存命中率 ≥ 60%”,AI 自動拆成每日可追蹤的北極星指標。??


九、總結

通過“EXIF 提取 → Maps 增強 → 視覺 caption → Few-Shot 提示工程”四連擊,我們把一堆靜態照片變成了可讀、可分享、可 SEO 的博客故事。

省流版

  1. 跑通 Colab → 2. 換自己的相冊 → 3. 一鍵生成 Markdown → 4. 發布到博客/公眾號

生成式 AI 不只是聊天,它也能成為你最會講故事的“旅行伙伴”。??

原文鏈接: https://medium.com/google-developer-experts/photo-storytelling-leveraging-generative-ai-and-google-apis-to-compose-posts-from-your-photo-cce8e30f4d57

熱門推薦
一個賬號試用1000+ API
助力AI無縫鏈接物理世界 · 無需多次注冊
3000+提示詞助力AI大模型
和專業工程師共享工作效率翻倍的秘密
返回頂部
上一篇
用 Instagram API 發照片:2025 開發者實戰指南
最后一篇
国内精品久久久久影院日本,日本中文字幕视频,99久久精品99999久久,又粗又大又黄又硬又爽毛片
亚洲国产精品成人久久综合一区| 欧美丰满一区二区免费视频| 美女视频免费一区| 丁香婷婷综合色啪| 欧美电影免费观看高清完整版 | 欧美美女网站色| 亚洲免费成人av| 国产aⅴ综合色| 久久在线免费观看| 久久91精品久久久久久秒播| 欧美性色黄大片| 亚洲免费观看高清完整| 色综合天天在线| 一区二区在线观看免费视频播放| 久久国产精品72免费观看| 欧美精品粉嫩高潮一区二区| 香蕉av福利精品导航| 在线综合+亚洲+欧美中文字幕| 午夜精品福利一区二区蜜股av| 欧美视频你懂的| 日韩精品久久久久久| 日韩美女在线视频 | 久久亚区不卡日本| 国产精品综合网| 国产精品人人做人人爽人人添| 国产精品1区二区.| 国产精品欧美极品| 色婷婷综合久久久中文字幕| 亚洲国产精品一区二区久久恐怖片| 欧美性受xxxx| 久久精品久久综合| 亚洲国产精品av| 欧洲人成人精品| 看片网站欧美日韩| 国产精品欧美经典| 欧美日精品一区视频| 国产在线一区观看| 亚洲摸摸操操av| 91精品国产高清一区二区三区蜜臀| 久久国产精品99久久久久久老狼 | 亚洲一区在线观看视频| 日韩欧美视频一区| 成人av第一页| 视频一区免费在线观看| 国产精品短视频| 精品对白一区国产伦| 日本韩国一区二区| 久久99精品久久久久| 亚洲一区二区三区免费视频| 欧美激情一区不卡| 91精品国产色综合久久不卡电影| 成人激情校园春色| 欧美日韩一级片在线观看| 国产高清精品久久久久| 亚洲午夜精品在线| 国产精品精品国产色婷婷| 日韩精品一区二区三区在线观看| 色婷婷综合久色| 懂色av一区二区三区免费看| 日本视频一区二区| 一区二区三区成人| 国产精品久久久久久亚洲伦 | 欧美日本一区二区在线观看| 99精品一区二区三区| 国产一区二区在线观看视频| 美国一区二区三区在线播放| 婷婷久久综合九色综合绿巨人| 亚洲一区二区三区视频在线播放| 一区二区不卡在线播放| 亚洲视频一二三区| 亚洲乱码中文字幕| 自拍av一区二区三区| 《视频一区视频二区| 国产精品毛片高清在线完整版| 欧美国产日韩a欧美在线观看| 国产欧美日本一区二区三区| 国产精品视频线看| 亚洲欧洲精品天堂一级| 亚洲精品国产高清久久伦理二区| 亚洲国产日韩一区二区| 日韩中文字幕不卡| 韩国v欧美v日本v亚洲v| 国产成人在线看| 97久久精品人人爽人人爽蜜臀| 色激情天天射综合网| 欧美一区二区三区白人| 久久―日本道色综合久久| 国产精品国产三级国产aⅴ中文 | 久久国产欧美日韩精品| 国产精品一品视频| 成人亚洲一区二区一| 欧美又粗又大又爽| 日韩一区二区电影在线| 国产欧美一区二区三区沐欲| 日韩一区欧美一区| 午夜私人影院久久久久| 国产一区二区在线看| av一区二区不卡| 欧美老女人第四色| 国产精品三级电影| 日韩av一级片| 99久久免费精品高清特色大片| 91丨九色丨蝌蚪富婆spa| 国产成都精品91一区二区三| 日韩av电影免费观看高清完整版| 国产精品123| 制服丝袜一区二区三区| 中文字幕日韩欧美一区二区三区| 日本va欧美va精品| 欧洲中文字幕精品| 国产精品色在线观看| 欧美a级理论片| 欧美在线一区二区三区| 国产精品亲子伦对白| 黄一区二区三区| 欧美一区欧美二区| 亚洲一区二区高清| 成人91在线观看| 欧美国产日本视频| 黄色日韩网站视频| 精品女同一区二区| 日本欧美在线看| 日韩一区和二区| 天堂资源在线中文精品| 一本大道久久a久久精品综合| 国产欧美日韩一区二区三区在线观看 | 不卡的av电影在线观看| 欧美日本高清视频在线观看| 国产欧美一区二区三区鸳鸯浴| 婷婷国产在线综合| eeuss鲁片一区二区三区| 欧美一区二区三区精品| 日本一区二区成人在线| 美女视频黄免费的久久 | 亚洲精品久久久蜜桃| 丰满岳乱妇一区二区三区| 久久一二三国产| 国产一区啦啦啦在线观看| 国产亚洲短视频| 九九在线精品视频| 久久精品视频网| 99v久久综合狠狠综合久久| 中文字幕一区二区三区不卡| 色婷婷久久综合| 亚洲18色成人| 久久嫩草精品久久久精品| 成人av网站免费观看| 亚洲午夜影视影院在线观看| 91精品视频网| 成人sese在线| 香蕉成人伊视频在线观看| 欧美一区二区三区思思人| 精品系列免费在线观看| 亚洲日本电影在线| 欧美一卡二卡三卡四卡| 国产福利视频一区二区三区| 亚洲精品高清在线观看| 欧美草草影院在线视频| www.欧美.com| 久久不见久久见免费视频1| 1000精品久久久久久久久| 欧美精品乱码久久久久久| 国产成人精品三级麻豆| 亚欧色一区w666天堂| 1000精品久久久久久久久| 日韩欧美中文字幕精品| 色狠狠色噜噜噜综合网| 国产精品亚洲专一区二区三区| 亚洲1区2区3区4区| 中文字幕一区二区在线观看| 成人激情综合网站| 夜夜嗨av一区二区三区中文字幕 | 成人av网站免费| 久久99热狠狠色一区二区| 亚洲一区二区三区四区在线免费观看| 久久久午夜电影| 日韩精品一区二区三区四区视频| 91高清在线观看| 一本色道亚洲精品aⅴ| 成人18视频在线播放| 懂色av一区二区三区免费观看| 国内精品嫩模私拍在线| 蜜桃久久久久久久| 国产拍欧美日韩视频二区| 久久伊人中文字幕| 日韩欧美精品在线| 欧美一区二区三区男人的天堂| 欧美亚洲动漫精品| 日本高清不卡在线观看| 91麻豆国产福利精品| 色综合久久久久综合体| 在线观看91精品国产入口| 91麻豆福利精品推荐| 欧美亚洲另类激情小说| 欧美日韩高清一区二区三区| 欧美日韩精品一区二区三区 | 欧美一区二区黄| 欧美电影免费观看高清完整版在| 欧美精品第一页| 狠狠色丁香婷婷综合久久片|