Bladeren bron

Resize selected letterhead to good dimensions

Uses gift package for server side resizing of selected letterhead
file. It should fit an image file with aspect ratio of 2:1 and be a
reasonable size. A 400x200 resizeToFit is used for now.
gift just uses the native image/draw package internally.
https://pkg.go.dev/image/draw
master
Immanuel Onyeka 1 jaar geleden
bovenliggende
commit
7055f5d6c7
6 gewijzigde bestanden met toevoegingen van 784 en 3014 verwijderingen
  1. +30
    -7
      components/settings.vue
  2. +1
    -0
      go.mod
  3. +2
    -0
      go.sum
  4. +713
    -3003
      package-lock.json
  5. +3
    -2
      package.json
  6. +35
    -2
      skouter.go

+ 30
- 7
components/settings.vue Bestand weergeven

@@ -16,10 +16,10 @@
<h3>Letterhead</h3>
<canvas class="displayer" height="200" ref="letterhead"></canvas>
<input type="file"
@change="e => changeLetterhead(e.target.files[0])"
@change="e => {setLetterhead(e.target.files[0])}"
/>
<button @click="uploadLetterhead">Upload</button>
<label class="error">{{avatarError}}</label>
<label class="error">{{letterheadError}}</label>
</section>

<section class="form inputs special">
@@ -68,6 +68,7 @@ let letterhead = ref(null) // the canvas element
let ready = ref(false)
let avatarChanged = ref(false)
let avatarError = ref('')
let letterHeadError = ref('')
let letterheadError = ref('')
const props = defineProps(['user', 'token'])
const emit = defineEmits(['updateAvatar', 'updateLetterhead'])
@@ -109,6 +110,28 @@ function uploadLetterhead() {
})
}

function setLetterhead(f) {
const validTypes = ['image/jpeg', 'image/png']
if (!validTypes.includes(f.type)) {
letterheadError.value = 'Image must be JPEG of PNG format'
return
}
fetch(`/api/letterhead`,
{method: 'POST',
body: f,
headers: {
"Accept": "application/json",
"Authorization": `Bearer ${props.token}`,
},
}).then(resp => {
if (resp.ok) {
resp.blob().then(b => changeLetterhead(b))
} else {
resp.text().then(e => letterheadError.value = e)
}
})
}

function changeAvatar(blob) {
const validTypes = ['image/jpeg', 'image/png']
@@ -135,13 +158,13 @@ function changeLetterhead(blob) {
return
}
letterheadError.value = ''
return createImageBitmap(blob,
{resizeWidth: 400, resizeHeight: 200, resizeQuality: 'medium'}).
createImageBitmap(blob).
then((img) => {
letterhead.value.getContext("2d").drawImage(img, 0, 0, 400, 200)
let ctx = letterhead.value.getContext("2d")
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height)
ctx.drawImage(img, 0, 0)
})

}

watch(props.user, (u) => {


+ 1
- 0
go.mod Bestand weergeven

@@ -4,6 +4,7 @@ go 1.19

require (
github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.0
github.com/disintegration/gift v1.2.1
github.com/go-sql-driver/mysql v1.6.0
github.com/golang-jwt/jwt/v4 v4.5.0
)

+ 2
- 0
go.sum Bestand weergeven

@@ -1,5 +1,7 @@
github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.0 h1:DNrExYwvyyI404SxdUCCANAj9TwnGjRfa3cYFMNY1AU=
github.com/SebastiaanKlippert/go-wkhtmltopdf v1.9.0/go.mod h1:SQq4xfIdvf6WYKSDxAJc+xOJdolt+/bc1jnQKMtPMvQ=
github.com/disintegration/gift v1.2.1 h1:Y005a1X4Z7Uc+0gLpSAsKhWi4qLtsdEcMIbbdvdZ6pc=
github.com/disintegration/gift v1.2.1/go.mod h1:Jh2i7f7Q2BM7Ezno3PhfezbR1xpUg9dUg3/RlKGr4HI=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=


+ 713
- 3003
package-lock.json
Diff onderdrukt omdat het te groot bestand
Bestand weergeven


+ 3
- 2
package.json Bestand weergeven

@@ -1,9 +1,10 @@
{
"scripts": {
"watch": "webpack --mode development --watch"
"watch": "webpack --mode development --watch"
},
"dependencies": {
"vue": "^3.2.41"
"vue": "^3.2.41",
"vue-html2pdf": "^1.8.0"
},
"devDependencies": {
"css-loader": "^6.7.1",


+ 35
- 2
skouter.go Bestand weergeven

@@ -20,6 +20,10 @@ import (
"io"
// pdf "github.com/SebastiaanKlippert/go-wkhtmltopdf"
"github.com/golang-jwt/jwt/v4"
"github.com/disintegration/gift"
"image"
"image/png"
_ "image/jpeg"
)

type User struct {
@@ -1566,12 +1570,13 @@ func checkFHA(l Loan, b Borrower) error {
return nil
}

// Loan option for veterans with no set rules
// Loan option for veterans with no set rules. Mainly placeholder.
func checkVA(l Loan, b Borrower) error {
return nil
}

// Loan option for residents of rural areas with no set rules
// Loan option for residents of rural areas with no set rules.
// Mainly placeholder.
func checkUSDA(l Loan, b Borrower) error {
return nil
}
@@ -1677,6 +1682,31 @@ func showPDF(w http.ResponseWriter, r *http.Request) {

}

func clipLetterhead(w http.ResponseWriter, db *sql.DB, r *http.Request) {
var validTypes []string = []string{"image/png", "image/jpeg"}
var isValidType bool
var err error
// claims, err := getClaims(r)
if err != nil { http.Error(w, "Invalid token.", 422); return }
img, t, err := image.Decode(r.Body)
if err != nil { http.Error(w, "Invalid file.", 422); return }
for _, v := range validTypes {
if v == "image/"+t { isValidType = true }
}
if !isValidType { http.Error(w, "Invalid file type.", 422); return }
g := gift.New(
gift.ResizeToFit(400, 200, gift.LanczosResampling),
)
dst := image.NewRGBA(g.Bounds(img.Bounds()))
g.Draw(dst, img)
w.Header().Set("Content-Type", "image/png")
err = png.Encode(w, dst)
if err != nil { http.Error(w, "Error encoding.", 500); return }
}

func api(w http.ResponseWriter, r *http.Request) {
var args []string

@@ -1702,6 +1732,9 @@ func api(w http.ResponseWriter, r *http.Request) {
case match(p, "/api/token", &args) &&
r.Method == http.MethodGet && guard(r, 1):
getToken(w, db, r)
case match(p, "/api/letterhead", &args) &&
r.Method == http.MethodPost && guard(r, 1):
clipLetterhead(w, db, r)
case match(p, "/api/users", &args) && // Array of all users
r.Method == http.MethodGet && guard(r, 3):
getUsers(w, db, r)


Laden…
Annuleren
Opslaan