本文目录导读:

在PHP项目中实现“图生文”(Image-to-Text)通常有两种主流方案:使用云端AI API 或 本地部署模型。
下面我会分别介绍这两种方案的具体实现步骤,并给出代码示例。
使用云端AI API(推荐,简单快速)
这是最常用的方式,适合大多数PHP项目,主流API包括:
- OpenAI GPT-4 Vision(最流行)
- 阿里云通义千问 VL
- 百度千帆(文心一言)
- 腾讯混元
示例:使用 OpenAI GPT-4 Vision API
安装依赖(通过 Composer)
composer require openai-php/client
PHP 代码实现
<?php
require 'vendor/autoload.php';
use OpenAI\Client;
class ImageToText
{
private $client;
public function __construct(string $apiKey)
{
$this->client = \OpenAI::client($apiKey);
}
/**
* 将图片转换为文字描述
*
* @param string $imagePath 图片路径(本地或URL)
* @param string $prompt 提示词(可选)
* @return string
*/
public function describe(string $imagePath, string $prompt = '请详细描述这张图片中有什么'): string
{
// 如果是本地文件,转为 base64
$imageData = $this->encodeImage($imagePath);
$response = $this->client->chat()->create([
'model' => 'gpt-4o', // 或 gpt-4-vision-preview
'messages' => [
[
'role' => 'user',
'content' => [
[
'type' => 'text',
'text' => $prompt
],
[
'type' => 'image_url',
'image_url' => [
'url' => $imageData
]
]
]
]
],
'max_tokens' => 1000
]);
return $response->choices[0]->message->content;
}
/**
* 将图片转为 base64 格式
*/
private function encodeImage(string $imagePath): string
{
// 如果是 URL,直接返回
if (filter_var($imagePath, FILTER_VALIDATE_URL)) {
return $imagePath;
}
// 本地文件
$imageData = file_get_contents($imagePath);
$mimeType = mime_content_type($imagePath);
return 'data:' . $mimeType . ';base64,' . base64_encode($imageData);
}
}
// 使用示例
$apiKey = 'your-openai-api-key';
$imageToText = new ImageToText($apiKey);
// 处理本地图片
$result = $imageToText->describe('/path/to/your/image.jpg');
echo $result;
// 处理网络图片
$result = $imageToText->describe('https://example.com/image.jpg');
echo $result;
使用阿里云通义千问 VL
如果项目在国内,推荐使用阿里云的视觉理解模型,速度快且稳定。
安装阿里云 SDK
composer require alibabacloud/client
PHP 代码实现
<?php
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
class AliyunImageToText
{
private $accessKeyId;
private $accessKeySecret;
public function __construct(string $accessKeyId, string $accessKeySecret)
{
$this->accessKeyId = $accessKeyId;
$this->accessKeySecret = $accessKeySecret;
AlibabaCloud::accessKeyClient($this->accessKeyId, $this->accessKeySecret)
->regionId('cn-shanghai')
->asDefaultClient();
}
/**
* 图片描述
*/
public function describe(string $imagePath): string
{
try {
// 将图片转为 base64
$imageBase64 = $this->encodeImage($imagePath);
$result = AlibabaCloud::rpc()
->product('AI')
->scheme('https') // https | http
->version('2022-06-01')
->action('ImageToText')
->method('POST')
->host('ai.cn-shanghai.aliyuncs.com')
->options([
'query' => [
'RegionId' => 'cn-shanghai',
'ImageUrl' => $imageBase64
]
])
->request();
return $result->toArray()['Data']['Text'];
} catch (ClientException $e) {
echo 'Client Exception: ' . $e->getErrorMessage() . PHP_EOL;
} catch (ServerException $e) {
echo 'Server Exception: ' . $e->getErrorMessage() . PHP_EOL;
}
}
private function encodeImage(string $imagePath): string
{
// 本地文件处理
if (!filter_var($imagePath, FILTER_VALIDATE_URL)) {
$imageData = file_get_contents($imagePath);
return base64_encode($imageData);
}
// URL图片需要先下载
$imageData = file_get_contents($imagePath);
return base64_encode($imageData);
}
}
// 使用
$aliyun = new AliyunImageToText('your-access-key-id', 'your-access-key-secret');
$text = $aliyun->describe('/path/to/image.jpg');
echo $text;
本地部署模型(离线方案)
如果需要离线处理(无网络、数据隐私要求高),可以在服务器本地运行模型。
推荐方案:使用 Python 微服务 + PHP 调用
Python 端(部署模型服务)
# image_to_text_service.py
from flask import Flask, request, jsonify
import base64
from PIL import Image
import io
# 假设使用 transformers 库加载模型(如 BLIP)
from transformers import BlipProcessor, BlipForConditionalGeneration
app = Flask(__name__)
# 加载模型
processor = BlipProcessor.from_pretrained("Salesforce/blip-image-captioning-base")
model = BlipForConditionalGeneration.from_pretrained("Salesforce/blip-image-captioning-base")
@app.route('/describe', methods=['POST'])
def describe_image():
data = request.json
image_data = base64.b64decode(data['image'])
image = Image.open(io.BytesIO(image_data))
inputs = processor(image, return_tensors="pt")
out = model.generate(**inputs)
description = processor.decode(out[0], skip_special_tokens=True)
return jsonify({'text': description})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
PHP 端调用
<?php
class LocalImageToText
{
private $serviceUrl;
public function __construct(string $serviceUrl = 'http://localhost:5000')
{
$this->serviceUrl = $serviceUrl;
}
public function describe(string $imagePath): string
{
// 读取图片并转为 base64
$imageData = base64_encode(file_get_contents($imagePath));
// 调用 Python 服务
$ch = curl_init($this->serviceUrl . '/describe');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['image' => $imageData]));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
return $result['text'] ?? '';
}
}
// 使用
$localService = new LocalImageToText();
echo $localService->describe('/path/to/image.jpg');
方案对比与选择建议
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| OpenAI API | 准确度高,支持多模态,文档完善 | 需要国外API Key,有网络延迟 | 国际项目,对准确度要求高 |
| 阿里云/百度云 | 国内速度快,合规性好 | 需要注册账号,按量计费 | 国内项目,企业级应用 |
| 本地部署模型 | 完全离线,隐私安全 | 需要GPU,模型准确度略低 | 数据敏感场景,高频处理 |
实战注意事项
- 图片格式支持:一般API支持 JPEG、PNG、GIF、WEBP
- 图片大小限制:建议压缩到 5MB 以内
- Base64 编码:大图片转 base64 会增大大小,考虑直接传 URL
- 错误处理:始终捕获 API 调用异常,做好降级方案
- 性能优化:对于批量图片,使用队列系统(如 Redis 队列)
完整项目示例(文件结构)
project/
├── composer.json
├── src/
│ └── ImageToText.php
├── config/
│ └── api.php
├── uploads/ # 图片存放目录
└── index.php # 入口文件
选择适合你项目需求的方案,推荐先用 OpenAI API 快速验证功能,后续根据实际情况迁移到国内API或本地模型。