Skip to content
This repository has been archived by the owner on Mar 28, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1643 from OpenBazaar/1630-handle-image-exif-rotation
Browse files Browse the repository at this point in the history
Allow EXIF data to be considered when uploading images
  • Loading branch information
placer14 authored Jul 8, 2019
2 parents ef06d07 + 04d9738 commit 8ec3315
Show file tree
Hide file tree
Showing 42 changed files with 5,177 additions and 2,017 deletions.
21 changes: 17 additions & 4 deletions Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 16 additions & 16 deletions api/jsonapi_data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,11 +229,11 @@ const avatarValidJSON = `{
}`

const avatarValidJSONResponse = `{
"large": "QmcUNDbsazULoEddnRSsiK1LgUCx6FnujgUG6r17GEviq2",
"medium": "Qmdj2NnzQwGuHN7RZmMhu1VEeLP7APDzFE5KmBKsPxZmuH",
"large": "QmWssRhf5pBARL5eiNSfvxJMC8UptqDsRNs71Vs8JYcquP",
"medium": "QmRCVZ9WSvS69Yv1uSFqwu87UW7TKsjfJY6CwfMNNiimaX",
"original": "QmYGE9UNEMvQ8W1qcVAMkJTYLpjNu1JHQtwqvppJ2QXiJe",
"small": "Qmf198F1mX2hhFJKkWUepxLh3vC853Xr79VQuhJFuBizZD",
"tiny": "QmPxXHGMm5J3y2G4S9brxe83CxLgt6D3MZKhxMBkNyKQWn"
"small": "QmcFz5VjvRzsjTARECw8EMX3GD7nW8xnEcCew4hAKTr6Mm",
"tiny": "QmYvRXkk9eW89R97jtWH5E8Uf6woHVvVrT3GqjVtVn8WCc"
}`

const avatarUnexpectedEOFJSON = `{
Expand All @@ -259,14 +259,14 @@ const imageValidJSON = `[{
}]`

const imageValidJSONResponse = `[{
"filename": "blue_tshirt.jpg",
"hashes": {
"large": "Qmcy4pW7cv18RMCprxrxhiihQzUJNaCNr5v2qvZGjGAwsj",
"medium": "QmVGiFSwTkMPjvGnnreHkspb9Ui2upkctYtqMR5sBKncHR",
"original": "QmQ2QdYMLCPWuVpdAvj49Kf7FvbpPrN4bdborHGb3G9jQv",
"small": "QmUBvfRXHYmzNx6uke5USD3C5PgWr5Wa3XHzcK3zaTeytS",
"tiny": "QmNi2H4MUkLe9eBEPmyE9QVQ6Y3F1RwpPxB4B1us5HnxwG"
}
"filename": "blue_tshirt.jpg",
"hashes": {
"large": "Qma36fP81juurtQetNpCABxNoiXyxPSHPaLV2qAsBwfz6u",
"medium": "QmYmEQvMRdrvYPpcy1wWDZw4Qpr82cfYeKBMi7igAGhpT1",
"original": "QmQ2QdYMLCPWuVpdAvj49Kf7FvbpPrN4bdborHGb3G9jQv",
"small": "QmUkYogFP4GAmTfFHiq1dtv8tc7UZGUhBX6DfZ7kfvwidT",
"tiny": "QmW3qn2BKeaxQvNTUJE1yXavLkseeut9VWNYb5Ew4tgjLJ"
}
}]`

// nolint lll
Expand All @@ -275,11 +275,11 @@ const headerValidJSON = `{
}`

const headerValidJSONResponse = `{
"large": "QmSqNf7gM4LKMsqej8b4q2su14TButMZduF5FJRodttbTZ",
"medium": "QmZqF47LXvKvKh5YyCerkEAiS4EmVubACeoQTQKXzU79WV",
"large": "QmPDHbQDjqMUfzDRrDAUxhh8KrgMTiijAoPKtN8EvxBN1A",
"medium": "QmP9KPZp1cexqkLr6MHJCQME7X76Z4NaFgty94MbXcxSHZ",
"original": "QmYGE9UNEMvQ8W1qcVAMkJTYLpjNu1JHQtwqvppJ2QXiJe",
"small": "QmQHHKV7cBFFE4WDJN9Vojxc3U14dt4dK5ihgtxwphdQij",
"tiny": "QmRheKdYREcdSHBdamY3ejZxh89UmnnjRQcqPPxAoQxn9X"
"small": "QmcnZDDJY9Ss4TZEFNsttUw8vUsr3Hdzqa5uB6P1TndCbd",
"tiny": "QmZrLG7ZSqNvrvcEsy7Zwd2Bb2SSxgAhkX4mrCDCtDJgER"
}`

//
Expand Down
57 changes: 26 additions & 31 deletions core/images.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ package core
import (
"bytes"
"encoding/base64"
"gx/ipfs/QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN/go-cid"
"image" // load gif
"image"
_ "image/gif"
"image/jpeg" // load png
jpeg "image/jpeg"
_ "image/png"
"io"
"io/ioutil"
Expand All @@ -19,10 +18,11 @@ import (
"time"

ipath "gx/ipfs/QmQAgv6Gaoe2tQpcabqwKXKChp2MZ7i3UXv9DqTTaxCaTR/go-path"
cid "gx/ipfs/QmTbxNB1NwDesLmKTscr4udL2tVP7MaxvXnD1D9yX7g3PN/go-cid"

"github.com/OpenBazaar/openbazaar-go/ipfs"
"github.com/OpenBazaar/openbazaar-go/pb"
"github.com/nfnt/resize"
"github.com/disintegration/imaging"
)

// SetAvatarImages - set avatar image from the base64 encoded image string
Expand Down Expand Up @@ -71,27 +71,27 @@ func (n *OpenBazaarNode) SetProductImages(base64ImageData, filename string) (*pb
return n.resizeImage(base64ImageData, filename, 120, 120)
}

func (n *OpenBazaarNode) resizeImage(base64ImageData, filename string, baseWidth, baseHeight uint) (*pb.Profile_Image, error) {
img, imgCfg, err := decodeImageData(base64ImageData)
func (n *OpenBazaarNode) resizeImage(base64ImageData, filename string, baseWidth, baseHeight int) (*pb.Profile_Image, error) {
img, err := decodeImageData(base64ImageData)
if err != nil {
return nil, err
}

imgPath := path.Join(n.RepoPath, "root", "images")

t, err := n.addResizedImage(img, imgCfg, 1*baseWidth, 1*baseHeight, path.Join(imgPath, "tiny", filename))
t, err := n.addResizedImage(img, 1*baseWidth, 1*baseHeight, path.Join(imgPath, "tiny", filename))
if err != nil {
return nil, err
}
s, err := n.addResizedImage(img, imgCfg, 2*baseWidth, 2*baseHeight, path.Join(imgPath, "small", filename))
s, err := n.addResizedImage(img, 2*baseWidth, 2*baseHeight, path.Join(imgPath, "small", filename))
if err != nil {
return nil, err
}
m, err := n.addResizedImage(img, imgCfg, 4*baseWidth, 4*baseHeight, path.Join(imgPath, "medium", filename))
m, err := n.addResizedImage(img, 4*baseWidth, 4*baseHeight, path.Join(imgPath, "medium", filename))
if err != nil {
return nil, err
}
l, err := n.addResizedImage(img, imgCfg, 8*baseWidth, 8*baseHeight, path.Join(imgPath, "large", filename))
l, err := n.addResizedImage(img, 8*baseWidth, 8*baseHeight, path.Join(imgPath, "large", filename))
if err != nil {
return nil, err
}
Expand All @@ -113,27 +113,22 @@ func (n *OpenBazaarNode) addImage(img image.Image, imgPath string) (string, erro
return ipfs.AddFile(n.IpfsNode, imgPath)
}

func (n *OpenBazaarNode) addResizedImage(img image.Image, imgCfg *image.Config, w, h uint, imgPath string) (string, error) {
width, height := getImageAttributes(w, h, uint(imgCfg.Width), uint(imgCfg.Height))
newImg := resize.Resize(width, height, img, resize.Lanczos3)
func (n *OpenBazaarNode) addResizedImage(img image.Image, w, h int, imgPath string) (string, error) {
width, height := getImageAttributes(w, h, img.Bounds().Max.X, img.Bounds().Max.Y)
newImg := imaging.Resize(img, width, height, imaging.Lanczos)
return n.addImage(newImg, imgPath)
}

func decodeImageData(base64ImageData string) (image.Image, *image.Config, error) {
func decodeImageData(base64ImageData string) (image.Image, error) {
reader := base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64ImageData))
img, _, err := image.Decode(reader)
img, err := imaging.Decode(reader, imaging.AutoOrientation(true))
if err != nil {
return nil, nil, err
}
reader = base64.NewDecoder(base64.StdEncoding, strings.NewReader(base64ImageData))
imgCfg, _, err := image.DecodeConfig(reader)
if err != nil {
return nil, nil, err
return nil, err
}
return img, &imgCfg, err
return img, err
}

func getImageAttributes(targetWidth, targetHeight, imgWidth, imgHeight uint) (width, height uint) {
func getImageAttributes(targetWidth, targetHeight, imgWidth, imgHeight int) (width, height int) {
targetRatio := float32(targetWidth) / float32(targetHeight)
imageRatio := float32(imgWidth) / float32(imgHeight)
var h, w float32
Expand All @@ -144,7 +139,7 @@ func getImageAttributes(targetWidth, targetHeight, imgWidth, imgHeight uint) (wi
w = float32(targetWidth)
h = float32(targetWidth) * (float32(imgHeight) / float32(imgWidth))
}
return uint(w), uint(h)
return int(w), int(h)
}

// FetchAvatar - fetch image avatar from ipfs
Expand Down Expand Up @@ -215,28 +210,28 @@ func (n *OpenBazaarNode) maybeMigrateImageHashes(listing *pb.Listing) error {
}

var err error
for i, image := range listing.Item.Images {
image.Large, err = maybeMigrateImage(image.Large, "large", image.Filename)
for i, img := range listing.Item.Images {
img.Large, err = maybeMigrateImage(img.Large, "large", img.Filename)
if err != nil {
return err
}
image.Medium, err = maybeMigrateImage(image.Medium, "medium", image.Filename)
img.Medium, err = maybeMigrateImage(img.Medium, "medium", img.Filename)
if err != nil {
return err
}
image.Small, err = maybeMigrateImage(image.Small, "small", image.Filename)
img.Small, err = maybeMigrateImage(img.Small, "small", img.Filename)
if err != nil {
return err
}
image.Tiny, err = maybeMigrateImage(image.Tiny, "tiny", image.Filename)
img.Tiny, err = maybeMigrateImage(img.Tiny, "tiny", img.Filename)
if err != nil {
return err
}
image.Original, err = maybeMigrateImage(image.Original, "original", image.Filename)
img.Original, err = maybeMigrateImage(img.Original, "original", img.Filename)
if err != nil {
return err
}
listing.Item.Images[i] = image
listing.Item.Images[i] = img
}
return nil
}
4 changes: 2 additions & 2 deletions core/images_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ import (

func TestImageFormats(t *testing.T) {
for _, image := range []string{jpgImageB64, gifImageB64, pngImageB64} {
_, cfg, err := decodeImageData(image)
img, err := decodeImageData(image)
if err != nil {
t.Error(err)
}
jpgImageB64 = "jfkdjfkd"
if cfg.Width != 50 || cfg.Height != 50 {
if img.Bounds().Max.X != 50 || img.Bounds().Max.Y != 50 {
t.Error("Incorrect sizes decoded")
}
}
Expand Down
14 changes: 14 additions & 0 deletions vendor/github.com/disintegration/imaging/.travis.yml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions vendor/github.com/disintegration/imaging/LICENSE

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 8ec3315

Please sign in to comment.