image - 如何使用 go 脚本在 Google-Cloud-Storage 中获取我的图像(base64)

标签 image google-app-engine go base64 google-cloud-storage

我一直在 go 中寻找示例 GAE 脚本从 PageSpeed Insights 的结果截图中获取我的图像并使用 Kohana/Cache 将其保存为 json_decode 对象到 Google 云存储 (GCS)

使用此方法的原因很简单,因为我发现此 Kohana 模型是将文件写入 GCS 的最便捷方式,尽管我也在寻找其他方式,例如 this使用 Blobstore 将文件写入 GCS在 Go API 文件已被弃用时为它们提供服务,如记录 here .

这是包含屏幕截图图像数据 (base64) 的存储对象的形式,该数据在默认应用程序存储桶中以公共(public)方式保存,对象名称为 images/thumb/mythumb.jpg :

stdClass Object
(
    [screenshot] => stdClass Object
        (
            [data] => _9j_4AAQSkZJRgABAQAAAQABAAD_...= // base64 data
            [height] => 240
            [mime_type] => image/jpeg
            [width] => 320
        )

    [otherdata] => Array
        (
            [..] => ..
            [..] => ..
        )

)

我想获取设置为 public 的图像使用我自定义的 url 如下,通过 go module 进行,我还需要它在特定时间过期,因为我已经设法定期更新图像内容本身:

http://myappId.appspot.com/image/thumb/mythumb.jpg

我在 disptach.yaml 中设置将所有图像请求发送到我的 go 模块,如下所示:

- url: "*/images/*"
  module: go

并在 go.yaml 中设置处理程序以按如下方式处理图像请求:

handlers:
- url: /images/thumb/.*
  script: _go_app

- url: /images
  static_dir: images

使用这个指令,我得到了所有 /images/ 请求(/images/thumb/ 请求除外)提供来自静态目录的图像,并且 /images/thumb/mythumb.jpg 转到模块应用程序。

所以在名为 thumb.go 的应用程序文件中留下了我必须使用的代码(参见 ????),如下所示:

package thumb

import(
    //what to import
    ????
    ????
)

const (
    googleAccessID            = "<serviceAccountEmail>@developer.gserviceaccount.com"
    serviceAccountPEMFilename = "YOUR_SERVICE_ACCOUNT_KEY.pem"
    bucket                    = "myappId.appspot.com"
)

var (
    expiration = time.Now().Add(time.Second * 60) //expire in 60 seconds
)

func init() {
    http.HandleFunc("/images/thumb/", handleThumb)
}

func handleThumb(w http.ResponseWriter, r *http.Request) {
    ctx := cloud.NewContext(appengine.AppID(c), hc)
    ???? //what code to get the string of 'mythumb.jpg' from url
    ???? //what code to get the image stored data from GCS
    ???? //what code to encoce base64 data
    w.Header().Set("Content-Type", "image/jpeg;")    
    fmt.Fprintf(w, "%v", mythumb.jpg)
}

我从一些例子中提取了很多代码,比如 this , thisthis但到目前为止还没有一件作品。我还尝试了 this 中的示例这几乎接近 my case但也没有找到运气。

所以一般情况下,主要是因为缺少在我用???? 标记的行上放置的正确代码以及要导入的相关库或路径。我还检查了 GCS permission如果按照描述丢失了某些东西 herehere .

非常感谢您的帮助和建议。

最佳答案

根据我在您的描述中所读到的内容,似乎唯一相关的部分是实际 Go 代码中的 ???? 行。如果情况并非如此,请告诉我。

首先????:“什么代码从url中获取'mythumb.jpg'的字符串”?

通过阅读代码,您希望从类似 http://localhost/images/thumb/mythumb.jpg 的 url 中提取 mythumb.jpgWriting Web Applications 提供了一个工作示例教程:

package main

import (
    "fmt"
    "net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "Hi there, I love %s!", r.URL.Path[1:])
}

func main() {
    http.HandleFunc("/", handler)
    http.ListenAndServe(":8080", nil)
}

这样

http://localhost:8080/monkeys

打印

Hi there, I love monkeys!

第二个????:“从GCS获取图像存储数据的代码是什么”?

您可能希望使用的 API 方法是 storage.objects.get .

您确实链接到了 JSON API Go Examples 之一对于 Google Cloud Storage,这是一个很好的一般引用,但与您要解决的问题无关。该特定示例是为客户端应用程序组合在一起的(因此 redirectURL = "urn:ietf:wg:oauth:2.0:oob" 行)。此外,此示例使用已弃用/过时的 oauth2 和存储包。

对于想要代表自己访问自己的存储桶的应用程序,最干净(且未弃用)的方法之一是使用 golang/oauth2Google APIs Client Library for Go包。

如何通过 golang/oauth2 使用 JSON Web Token auth 进行身份验证的示例包裹是available in the repo :

func ExampleJWTConfig() {
    conf := &jwt.Config{
        Email: "xxx@developer.com",
        // The contents of your RSA private key or your PEM file
        // that contains a private key.
        // If you have a p12 file instead, you
        // can use `openssl` to export the private key into a pem file.
        //
        //    $ openssl pkcs12 -in key.p12 -out key.pem -nodes
        //
        // It only supports PEM containers with no passphrase.
        PrivateKey: []byte("-----BEGIN RSA PRIVATE KEY-----..."),
        Subject:    "user@example.com",
        TokenURL:   "https://provider.com/o/oauth2/token",
    }
    // Initiate an http.Client, the following GET request will be
    // authorized and authenticated on the behalf of user@example.com.
    client := conf.Client(oauth2.NoContext)
    client.Get("...")
}

接下来,不要直接使用 oauth2 客户端,而是使用带有 Google APIs Client Library for Go 的客户端前面提到:

service, err := storage.New(client)
if err != nil {
    fatalf(service, "Failed to create service %v", err)
}

注意与过时的 JSON API Go Examples 的相似之处?

在您的处理程序中,您需要使用 func ObjectsService.Get 获取相关对象。 .假设您知道 objectbucket 的名称,即。

直接从前面的示例中,您可以使用类似于下面的代码来检索下载链接:

if res, err := service.Objects.Get(bucketName, objectName).Do(); err == nil {
    fmt.Printf("The media download link for %v/%v is %v.\n\n", bucketName, res.Name, res.MediaLink)
} else {
    fatalf(service, "Failed to get %s/%s: %s.", bucketName, objectName, err)
}

然后,获取文件,或者用它做任何你想做的事。完整示例:

import (
    "golang.org/x/oauth2"
    "golang.org/x/oauth2/jwt"
    "google.golang.org/api/storage/v1"
    "fmt"
)

...

const (
    bucketName = "YOUR_BUCKET_NAME"
    objectName = "mythumb.jpg"
)

func main() {
    conf := &jwt.Config{
        Email: "xxx@developer.com",
        PrivateKey: []byte("-----BEGIN RSA PRIVATE KEY-----..."),
        Subject:    "user@example.com",
        TokenURL:   "https://provider.com/o/oauth2/token",
     }

    client := conf.Client(oauth2.NoContext)

    service, err := storage.New(client)
    if err != nil {
        fatalf(service, "Failed to create service %v", err)
    }

    if res, err := service.Objects.Get(bucketName, objectName).Do(); err == nil {
        fmt.Printf("The media download link for %v/%v is %v.\n\n", bucketName, res.Name, res.MediaLink)
    } else {
        fatalf(service, "Failed to get %s/%s: %s.", bucketName, objectName, err)
    }

    // Go fetch the file, etc.
}

第三个????:“编码base64数据的代码是什么”?

使用 encoding/base64 非常简单包裹。如此简单,他们包括了一个 example :

package main

import (
    "encoding/base64"
    "fmt"
)

func main() {
    data := []byte("any + old & data")
    str := base64.StdEncoding.EncodeToString(data)
    fmt.Println(str)
}

希望对您有所帮助。

关于image - 如何使用 go 脚本在 Google-Cloud-Storage 中获取我的图像(base64),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29148777/

相关文章:

Golang libphonenumber

java - 将现有图像添加到 Canvas

java - PNG 图像在 Itext7 中被损坏

php - 对于图片上传,我应该在MYSQL数据库中添加一个字段来检查,还是简单地使用PHP来检查图片是否存在?

python - 限制 IP 地址以访问您在 GAE 上的应用程序?

java - 为什么 objectify 的 put() 函数不抛出异常?

go - 如何导入 "sibling"包?

java - java 中的字节数组未显示图像

google-app-engine - 使用 JavaMail 的电子邮件通知

go - 如何分发 Go 应用程序?