Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Golang我如何上传外部图像而不旋转它们_Go_Decode - Fatal编程技术网

Golang我如何上传外部图像而不旋转它们

Golang我如何上传外部图像而不旋转它们,go,decode,Go,Decode,我已经在一个图像上传功能上工作了几个星期,我几乎已经完成了。我使用Golang作为后端语言,其目的是将从IOS设备发送的图像上传到AmazonS3。在上传图像的过程中,我也调整了它们的大小,这主要导致了问题,解码方法有时会旋转我不想要的图像 file, handler, err := r.FormFile("file") if err != nil { fmt.Println("Error Uploading Image") ret

我已经在一个图像上传功能上工作了几个星期,我几乎已经完成了。我使用Golang作为后端语言,其目的是将从IOS设备发送的图像上传到AmazonS3。在上传图像的过程中,我也调整了它们的大小,这主要导致了问题,解码方法有时会旋转我不想要的图像

file, handler, err := r.FormFile("file")
        if err != nil {
            fmt.Println("Error Uploading Image")
            return
        }
        defer file.Close()
         // the code below sometimes rotates an image
        img,err := imaging.Decode(file)
        if err != nil {
            print("Imaging Open error")
        }
      new_image := imaging.Resize(img,400,400, imaging.Lanczos)
我使用的这个库非常棒,他们展示的例子是

src, err := imaging.Open("testdata/lena_512.png")
    if err != nil {
        log.Fatalf("Open failed: %v", err)
    }

    src = imaging.Resize(src, 256, 0, imaging.Lanczos)
这个例子很好,但是我的图像不是本地存储的,它们来自IOS设备。我可以做些什么来解决这个问题吗?我的一些图像是这样保存的

有些图像是这样旋转的,这是解码方法

我可以通过旋转图像来纠正它,但是其他一些未通过解码旋转的图像最终被旋转270方法旋转

img,err := imaging.Decode(file)
        if err != nil {
            print("Imaging Open error")
        }
         // rotate the image
        img = imaging.Rotate270(img)

        new_image := imaging.Resize(img,400,400, imaging.Lanczos)
这是如何保存图像,并在旋转图像后进行查看。是否有什么方法可以上传外部图像而不必使用解码或只是修复解码问题?Imaging.Resize第一个参数采用类型image.image,这是我的完整代码

func myImages(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()
    var buff bytes.Buffer
file, handler, err := r.FormFile("file")
        if err != nil {
            fmt.Println("Error Uploading Image")
            return
        }
        defer file.Close()

        img,err := imaging.Decode(file)
        if err != nil {
            print("Imaging Open error")
        }


        new_image := imaging.Resize(img,400,400, imaging.Lanczos)
        var buf bytes.Buffer




        err = imaging.Encode(&buf,new_image, imaging.JPEG)
        if err != nil {
            log.Println(err)
            return
        }
    }

不幸的是,go stdlib图像包无法处理标记为使用exif标签旋转的图像(如此处倒置在设备上拍摄的图像)。这方面的错误如下:

您可以在camlistore中看到一个处理此问题的示例,但它非常复杂:

首先,您必须解码exif选项(DecodeOpts),然后您必须检查它的方向(可能有8个方向),然后根据需要旋转。这很痛苦,目前还没有简单的解决办法。您可以通过以下方式使用此软件包读取exif数据:


我遇到了同样的问题,在两个库的帮助下解决了这个问题:

go get -u github.com/disintegration/imaging
go get -u github.com/rwcarlsen/goexif/exif
使用exif可以获得图像的实际方向,使用成像可以执行将图像恢复到方向1所需的操作。 由于替换的图像没有exif信息,因此结果将正确显示

// ReadImage makes a copy of image (jpg,png or gif) and applies
// all necessary operation to reverse its orientation to 1
// The result is a image with corrected orientation and without
// exif data.
func ReadImage(fpath string) *image.Image {
    var img image.Image
    var err error
    // deal with image
    ifile, err := os.Open(fpath)
    if err != nil {
        logrus.Warnf("could not open file for image transformation: %s", fpath)
        return nil
    }
    defer ifile.Close()
    filetype, err := GetSuffix(fpath)
    if err != nil {
        return nil
    }
    if filetype == "jpg" {
        img, err = jpeg.Decode(ifile)
        if err != nil {
            return nil
        }
    } else if filetype == "png" {
        img, err = png.Decode(ifile)
        if err != nil {
            return nil
        }
    } else if filetype == "gif" {
        img, err = gif.Decode(ifile)
        if err != nil {
            return nil
        }
    }
    // deal with exif
    efile, err := os.Open(fpath)
    if err != nil {
        logrus.Warnf("could not open file for exif decoder: %s", fpath)
    }
    defer efile.Close()
    x, err := exif.Decode(efile)
    if err != nil {
        if x == nil {
            // ignore - image exif data has been already stripped
        }
        logrus.Errorf("failed reading exif data in [%s]: %s", fpath, err.Error())
    }
    if x != nil {
        orient, _ := x.Get(exif.Orientation)
        if orient != nil {
            logrus.Infof("%s had orientation %s", fpath, orient.String())
            img = reverseOrientation(img, orient.String())
        } else {
            logrus.Warnf("%s had no orientation - implying 1", fpath)
            img = reverseOrientation(img, "1")
        }
        imaging.Save(img, fpath)
    }
    return &img
}

// reverseOrientation amply`s what ever operation is necessary to transform given orientation
// to the orientation 1
func reverseOrientation(img image.Image, o string) *image.NRGBA {
    switch o {
    case "1":
        return imaging.Clone(img)
    case "2":
        return imaging.FlipV(img)
    case "3":
        return imaging.Rotate180(img)
    case "4":
        return imaging.Rotate180(imaging.FlipV(img))
    case "5":
        return imaging.Rotate270(imaging.FlipV(img))
    case "6":
        return imaging.Rotate270(img)
    case "7":
        return imaging.Rotate90(imaging.FlipV(img))
    case "8":
        return imaging.Rotate90(img)
    }
    logrus.Errorf("unknown orientation %s, expect 1-8", o)
    return imaging.Clone(img)
}
您也可以在此处找到此实现:

解码没有旋转图像,图像最初是在显示时由于退出方向标签而旋转的。您必须读取该标记以确定如何旋转图像。您应该检查图片中的Exif数据。我猜旋转图片的不是成像。