全部產品
Search
文件中心

Object Storage Service:圖片處理持久化

更新時間:Jun 19, 2024

OSS會根據請求的參數即時產生圖片,預設不儲存處理後的圖片。對於經常需要展示相同處理結果(例如縮圖、裁剪圖或格式轉換後的圖片)的應用情境,您可以選擇OSS圖片處理持久化功能。圖片處理持久化支援在圖片處理的請求中添加轉存參數,並將處理後的圖片儲存至指定的Bucket,助力您更高效地管理和分發圖片資源。

注意事項

  • 許可權要求

    進行圖片轉存操作要求具有源Bucket的oss:PostProcessTask許可權,以及目標Bucket的oss:PutBucket和目標Object的oss:PutObject許可權。

  • 儲存地區

    原圖所在Bucket和處理後圖片轉存的目標Bucket可以相同也可以不同,但必須屬於同一帳號下的相同地區。

  • 轉存方式

    • 支援通過添加轉存參數的方式將阿里雲SDK處理後的圖片儲存至指定Bucket。具體操作,請參見阿里雲SDK圖片處理持久化樣本

    • 不支援將檔案URL處理後的圖片直接轉存至指定Bucket。您可以將處理後的圖片儲存到本地,然後再上傳至指定Bucket。

  • 轉存圖片讀寫權限ACL

    轉存圖片的讀寫權限ACL預設繼承Bucket,不支援自訂。

  • 轉存圖片儲存時間長度

    如果您需要調整轉存圖片的儲存時間長度,請結合生命週期規則配置合理的檔案到期策略。

操作步驟

使用阿里雲SDK

以下僅列舉常見SDK的圖片處理持久化的程式碼範例。關於其他SDK的圖片處理持久化的程式碼範例,請參見SDK簡介

import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.common.utils.IOUtils;
import com.aliyun.oss.model.GenericResult;
import com.aliyun.oss.model.ProcessObjectRequest;
import java.util.Formatter;

public class Demo {
    public static void main(String[] args) throws Throwable {
        // Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "examplebucket";
        // 填寫Object完整路徑。Object完整路徑中不能包含Bucket名稱。
        String sourceImage = "exampleimage.png";

        // 建立OSSClient執行個體。
        OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);

        try {
            // 將圖片縮放為固定寬高100 px。
            StringBuilder sbStyle = new StringBuilder();
            Formatter styleFormatter = new Formatter(sbStyle);
            String styleType = "image/resize,m_fixed,w_100,h_100";
            // 將處理後的圖片命名為example-resize.png並儲存到當前Bucket。
            // 填寫Object完整路徑。Object完整路徑中不能包含Bucket名稱。
            String targetImage = "example-resize.png";
            styleFormatter.format("%s|sys/saveas,o_%s,b_%s", styleType,
                    BinaryUtil.toBase64String(targetImage.getBytes()),
                    BinaryUtil.toBase64String(bucketName.getBytes()));
            System.out.println(sbStyle.toString());
            ProcessObjectRequest request = new ProcessObjectRequest(bucketName, sourceImage, sbStyle.toString());
            GenericResult processResult = ossClient.processObject(request);
            String json = IOUtils.readStreamAsString(processResult.getResponse().getContent(), "UTF-8");
            processResult.getResponse().getContent().close();
            System.out.println(json);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;

// 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
$provider = new EnvironmentVariableCredentialsProvider();
// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
$endpoint = "yourEndpoint";
// 填寫Bucket名稱,例如examplebucket。
$bucket= "examplebucket";
// 填寫源Object完整路徑,例如exampledir/exampleobject.jpg。Object完整路徑中不能包含Bucket名稱。
$object = "exampledir/exampleobject.jpg";
// 填寫目標Object完整路徑,例如example-new.jpg。
$save_object = "example-new.jpg";

function base64url_encode($data)
{
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

$config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
    );
    $ossClient = new OssClient($config);
// 如果靶心圖表片不在指定Bucket中,需上傳圖片到目標Bucket。
// $ossClient->uploadFile($bucket, $object, "D:\\localpath\\exampleobject.jpg");

// 將圖片縮放為固定寬高100 px後,再旋轉90°。
$style = "image/resize,m_fixed,w_100,h_100/rotate,90";

$process = $style.
           '|sys/saveas'.
           ',o_'.base64url_encode($save_object).
           ',b_'.base64url_encode($bucket);

// 將處理後的圖片命名為example-new.png並儲存到當前Bucket。
$result = $ossClient->processObject($bucket, $object, $process);
// 列印處理結果。
print($result);
const OSS = require('ali-oss');

const client = new OSS({
  // yourregion填寫Bucket所在地區。以華東1(杭州)為例,Region填寫為oss-cn-hangzhou。
  region: 'yourregion',
  // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,
  // yourbucketname填寫儲存空間名稱。
  bucket: 'yourbucketname'
});

const sourceImage = 'sourceObject.png';
const targetImage = 'targetObject.jpg';
async function processImage(processStr, targetBucket) {
  const result = await client.processObjectSave(
    sourceImage,
    targetImage,
    processStr,
    targetBucket
  );
  console.log(result.res.status);
}

// 圖片處理持久化:縮放,並設定儲存圖片處理持久化結果的目標bucket。
processImage("image/resize,m_fixed,w_100,h_100", "target bucket")

// 圖片處理持久化:裁剪,並設定儲存圖片處理持久化結果的目標bucket。
processImage("image/crop,w_100,h_100,x_100,y_100,r_1", "target bucket")

// 圖片處理持久化:旋轉,並設定儲存圖片處理持久化結果的目標bucket。
processImage("image/rotate,90", "target bucket")

// 圖片處理持久化:銳利化,並設定儲存圖片處理持久化結果的目標bucket。
processImage("image/sharpen,100", "target bucket")

// 圖片處理持久化:浮水印,並設定儲存圖片處理持久化結果的目標bucket。
processImage("image/watermark,text_SGVsbG8g5Zu-54mH5pyN5YqhIQ", "target bucket")

// 圖片處理持久化:格式轉換,並設定儲存圖片處理持久化結果的目標bucket。
processImage("image/format,jpg", "target bucket")

// 圖片處理持久化:格式轉換,並設定儲存圖片處理持久化結果的目標bucket。
processImage("image/format,jpg", "target bucket")
# -*- coding: utf-8 -*-
import os
import base64
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider

# 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
# 填寫Bucket名稱。
bucket = oss2.Bucket(auth, 'https://oss-cn-hangzhou.aliyuncs.com', 'examplebucket')
# 指定原圖所在的Bucket名稱。
source_bucket_name = 'srcbucket'
# 指定用於存放處理後圖片的Bucket名稱,該Bucket需與原圖所在Bucket在同一地區。
target_bucket_name = 'destbucket'
# 指定原圖名稱。如果圖片不在Bucket根目錄,需攜帶檔案完整訪問路徑,例如example/example.jpg。
source_image_name = 'example/example.jpg'

# 將圖片縮放為固定寬高100 px。
style = 'image/resize,m_fixed,w_100,h_100'
# 指定處理後圖片名稱。如果圖片不在Bucket根目錄,需攜帶檔案完整訪問路徑,例如exampledir/example.jpg。
target_image_name = 'exampledir/example.jpg'
process = "{0}|sys/saveas,o_{1},b_{2}".format(style, 
    oss2.compat.to_string(base64.urlsafe_b64encode(oss2.compat.to_bytes(target_image_name))),
    oss2.compat.to_string(base64.urlsafe_b64encode(oss2.compat.to_bytes(target_bucket_name))))
result = bucket.process_object(source_image_name, process)
print(result)
// fromBucket和toBucket分別表示源Bucket和目的Bucket名稱。
// fromObjectKey和toObjectkey分別表示源Object和目標Object名稱,其填寫格式為指定包含檔案尾碼在內的完整路徑,例如abc/efg/123.jpg。
// action表示圖片處理操作,如上面樣本提到的"image/resize,m_lfit,w_100,h_100"。
ImagePersistRequest request = new ImagePersistRequest(fromBucket,fromObjectKey,toBucket,toObjectkey,action);

        OSSAsyncTask task = oss.asyncImagePersist(request, new OSSCompletedCallback<ImagePersistRequest, ImagePersistResult>() {
            @Override
            public void onSuccess(ImagePersistRequest request, ImagePersistResult result) {
                // sucess callback
                log.i("info", "Success");
            }

            @Override
            public void onFailure(ImagePersistRequest request, ClientException clientException, ServiceException serviceException) {
              // 請求異常。
              if (clientException != null) {
                  // 用戶端異常,例如網路異常等。
                  clientException.printStackTrace();
              }
              if (serviceException != null) {
                  // 服務端異常。
                  Log.e("ErrorCode", serviceException.getErrorCode());
                  Log.e("RequestId", serviceException.getRequestId());
                  Log.e("HostId", serviceException.getHostId());
                  Log.e("RawMessage", serviceException.getRawMessage());
              }
            }
        });
package main

import (
    "encoding/base64"
    "fmt"
    "github.com/aliyun/aliyun-oss-go-sdk/oss"
    "os"
)

func HandleError(err error) {
    fmt.Println("Error:", err)
    os.Exit(-1)
}

func main() {
    // 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
    provider, err := oss.NewEnvironmentVariableCredentialsProvider()
    if err != nil {
    fmt.Println("Error:", err)
    os.Exit(-1)
    }

    // 建立OSSClient執行個體。
    // yourEndpoint填寫Bucket對應的Endpoint,以華東1(杭州)為例,填寫為https://oss-cn-hangzhou.aliyuncs.com。其它Region請按實際情況填寫。
    client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
    if err != nil {
    HandleError(err)
    }

    // 指定原圖所在Bucket的名稱,例如srcbucket。
    bucketName := "SourceBucketName"
    bucket, err := client.Bucket(bucketName)
    if err != nil {
    HandleError(err)
    }
    // 指定原圖名稱。如果圖片不在Bucket根目錄,需攜帶檔案完整路徑,例如example/example.jpg。
    sourceImageName := "yourObjectName"
    // 指定用於存放處理後圖片的Bucket名稱,該Bucket需與原圖所在Bucket在同一地區。
    targetBucketName := "TargetBucketName"
    // 指定處理後圖片名稱。如果圖片不在Bucket根目錄,需攜帶檔案完整訪問路徑,例如exampledir/example.jpg。
    targetImageName := "TargetObjectName"
    // 將圖片縮放為固定寬高100 px後轉存到指定儲存空間。
    style := "image/resize,m_fixed,w_100,h_100"
    process := fmt.Sprintf("%s|sys/saveas,o_%v,b_%v", style, base64.URLEncoding.EncodeToString([]byte(targetImageName)), base64.URLEncoding.EncodeToString([]byte(targetBucketName)))
    result, err := bucket.ProcessObject(sourceImageName, process)
    if err != nil {
    HandleError(err)
    } else {
    fmt.Println(result)
    }
}
OSSImagePersistRequest *request = [OSSImagePersistRequest new];
// 填寫原圖所在Bucket的名稱。
request.fromBucket = @"srcbucket";
// 填寫原圖名稱。如果圖片不在Bucket根目錄,需攜帶檔案完整路徑,例如exampledir/src.jpg。
request.fromObject = @"exampledir/src.jpg";
// 填寫處理後圖片存放的Bucket名稱,該Bucket需與源Bucket在相同地區。
request.toBucket = @"destbucket";
// 填寫處理後的圖片名稱.
request.toObject = @"exampledir/dest.jpg";
// 將圖片按比例縮放至寬100 px後轉存到指定Bucket。
request.action = @"image/resize,w_100";
//request.action = @"resize,w_100";

[[[ossClient imageActionPersist:request] continueWithBlock:^id _Nullable(OSSTask * _Nonnull task) {

    return nil;
}] waitUntilFinished];
#include <alibabacloud/oss/OssClient.h>
#include <sstream>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* 初始化OSS帳號資訊。*/
            
    /* 指定Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
    std::string Endpoint = "yourEndpoint";
    /* 指定Bucket名稱,例如examplebucket。*/
    std::string BucketName = "examplebucket";
    /* 指定原圖名稱。如果圖片不在Bucket根目錄,需攜帶檔案完整路徑,例如example/example.jpg。*/
    std::string SourceObjectName = "example/example.jpg";
    /* 指定處理後圖片名稱。如果圖片不在Bucket根目錄,需攜帶檔案完整訪問路徑,例如exampledir/example.jpg。*/
    std::string TargetObjectName = "exampledir/example.jpg";

    /* 初始化網路等資源。*/
    InitializeSdk();

    ClientConfiguration conf;
    /* 從環境變數中擷取訪問憑證。運行本程式碼範例之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。*/
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);

    /* 將圖片縮放為固定寬高100 px後轉存到當前Bucket。*/
    std::string Process = "image/resize,m_fixed,w_100,h_100";
    std::stringstream ss;
    ss  << Process 
    <<"|sys/saveas"
    << ",o_" << Base64EncodeUrlSafe(TargetObjectName)
    << ",b_" << Base64EncodeUrlSafe(BucketName);
    ProcessObjectRequest request(BucketName, SourceObjectName, ss.str());
    auto outcome = client.ProcessObject(request);
    if (outcome.isSuccess()) {
    std::cout << "Image processed successfully." << std::endl;
    } else {
    std::cout << "Failed to process image. Error code: " << outcome.error().Code()
              << ", Message: " << outcome.error().Message()
              << ", RequestId: " << outcome.error().RequestId() << std::endl;
    }

    /* 釋放網路等資源。*/
    ShutdownSdk();
    return 0;
}

使用REST API

如果您的程式自訂要求較高,您可以直接發起REST API請求。直接發起REST API請求需要手動編寫代碼計算簽名。

使用saveas參數時,您需要攜帶以下選項:

選項

含義

o

目標Object名稱,名稱需經過URL Safe的Base64編碼。具體操作,請參見浮水印編碼

b

目標Bucket名稱,名稱需經過URL Safe的Base64編碼。如果不指定目標Bucket,則預設儲存至原圖所在Bucket。

您可以通過以下兩種方式處理圖片並將圖片轉存至指定Bucket。

  • 使用圖片處理參數處理圖片並轉存至指定Bucket,樣本如下:

    POST /ObjectName?x-oss-process HTTP/1.1
    Host: oss-example.oss.aliyuncs.com
    Content-Length: 247
    Date: Fri, 04 May 2012 03:21:12 GMT
    Authorization: OSS qn6q**************:77Dv****************
    
    // 將靶心圖表片test.jpg等比縮放為寬100 px後,儲存到名為test的Bucket中。
    x-oss-process=image/resize,w_100|sys/saveas,o_dGVzdC5qcGc,b_dGVzdA
  • 使用樣式處理圖片並轉存至指定Bucket,樣本如下:

    POST /ObjectName?x-oss-process HTTP/1.1
    Host: oss-example.oss.aliyuncs.com
    Content-Length: 247
    Date: Fri, 04 May 2012 03:22:13 GMT
    Authorization: OSS qn6q**************:77Dv****************
    
    // 使用名為examplestyle的樣式處理靶心圖表片test.jpg後,儲存到名為test的Bucket中。
    x-oss-process=style/examplestyle|sys/saveas,o_dGVzdC5qcGc,b_dGVzdA