add image by URL and limit size on API

This commit is contained in:
Tiago Vasconcelos 2023-01-11 16:33:01 +00:00
parent e886d17f15
commit fc7a799b89
3 changed files with 49 additions and 11 deletions

View file

@ -4,6 +4,15 @@ Vue.component(VueQrcode.name, VueQrcode)
const pica = window.pica() const pica = window.pica()
function imgSizeFit(img, maxWidth = 1024, maxHeight = 768) {
let ratio = Math.min(
1,
maxWidth / img.naturalWidth,
maxHeight / img.naturalHeight
)
return {width: img.naturalWidth * ratio, height: img.naturalHeight * ratio}
}
const defaultItemData = { const defaultItemData = {
unit: 'sat' unit: 'sat'
} }
@ -23,6 +32,7 @@ new Vue({
}, },
itemDialog: { itemDialog: {
show: false, show: false,
urlImg: true,
data: {...defaultItemData}, data: {...defaultItemData},
units: ['sat'] units: ['sat']
} }
@ -41,6 +51,9 @@ new Vue({
openUpdateDialog(itemId) { openUpdateDialog(itemId) {
this.itemDialog.show = true this.itemDialog.show = true
let item = this.offlineshop.items.find(item => item.id === itemId) let item = this.offlineshop.items.find(item => item.id === itemId)
if (item.image.startsWith('data:')) {
this.itemDialog.urlImg = false
}
this.itemDialog.data = item this.itemDialog.data = item
}, },
imageAdded(file) { imageAdded(file) {
@ -48,17 +61,12 @@ new Vue({
let image = new Image() let image = new Image()
image.src = blobURL image.src = blobURL
image.onload = async () => { image.onload = async () => {
let fit = imgSizeFit(image, 100, 100)
let canvas = document.createElement('canvas') let canvas = document.createElement('canvas')
canvas.setAttribute('width', 100) canvas.setAttribute('width', fit.width)
canvas.setAttribute('height', 100) canvas.setAttribute('height', fit.height)
await pica.resize(image, canvas, { output = await pica.resize(image, canvas)
quality: 0, this.itemDialog.data.image = output.toDataURL('image/jpeg', 0.4)
alpha: true,
unsharpAmount: 95,
unsharpRadius: 0.9,
unsharpThreshold: 70
})
this.itemDialog.data.image = canvas.toDataURL()
this.itemDialog = {...this.itemDialog} this.itemDialog = {...this.itemDialog}
} }
}, },
@ -155,6 +163,7 @@ new Vue({
this.loadShop() this.loadShop()
this.itemDialog.show = false this.itemDialog.show = false
this.itemDialog.urlImg = true
this.itemDialog.data = {...defaultItemData} this.itemDialog.data = {...defaultItemData}
}, },
toggleItem(itemId) { toggleItem(itemId) {

View file

@ -237,7 +237,7 @@
<q-responsive v-if="itemDialog.data.id" :ratio="1"> <q-responsive v-if="itemDialog.data.id" :ratio="1">
<qrcode <qrcode
:value="'lightning:' + itemDialog.data.lnurl" :value="'lightning:' + itemDialog.data.lnurl"
:options="{width: 800}" :options="{width: 300}"
class="rounded-borders" class="rounded-borders"
></qrcode> ></qrcode>
</q-responsive> </q-responsive>
@ -266,7 +266,16 @@
type="text" type="text"
label="Brief description" label="Brief description"
></q-input> ></q-input>
<q-input
v-if="itemDialog.urlImg"
filled
dense
v-model.trim="itemDialog.data.image"
type="url"
label="Image URL"
></q-input>
<q-file <q-file
v-else
filled filled
dense dense
capture="environment" capture="environment"
@ -288,6 +297,10 @@
/> />
</template> </template>
</q-file> </q-file>
<q-toggle
:label="`${itemDialog.urlImg ? 'Insert image URL' : 'Upload image file'}`"
v-model="itemDialog.urlImg"
></q-toggle>
<q-input <q-input
filled filled
dense dense

View file

@ -60,6 +60,22 @@ async def api_add_or_update_item(
): ):
shop = await get_or_create_shop_by_wallet(wallet.wallet.id) shop = await get_or_create_shop_by_wallet(wallet.wallet.id)
assert shop assert shop
if data.image:
image_is_url = data.image.startswith("https://") or data.image.startswith(
"http://"
)
if not image_is_url:
def size(b64string):
return int((len(b64string) * 3) / 4 - b64string.count("=", -2))
image_size = size(data.image) / 1024
if image_size > 100:
raise HTTPException(
status_code=HTTPStatus.BAD_REQUEST,
detail=f"Image size is too big, {int(image_size)}Kb. Max: 100kb, Compress the image at https://tinypng.com, or use an URL.",
)
if data.unit != "sat": if data.unit != "sat":
data.price = data.price * 100 data.price = data.price * 100
if item_id == None: if item_id == None: