Crop print border on upload

This commit is contained in:
Natsumi
2025-03-14 06:56:24 +13:00
parent 6b6663f803
commit 9ed93ad2eb
8 changed files with 48 additions and 17 deletions

View File

@@ -204,13 +204,9 @@ namespace VRCX
var ms = new MemoryStream(bytes);
var print = await Image.LoadAsync(ms);
// validation step to ensure image is actually a print
if (print.Width != 2048 || print.Height != 1440)
if (!CropPrint(ref print))
return false;
var point = new Point(64, 69);
var size = new Size(1920, 1080);
var rectangle = new Rectangle(point, size);
print.Mutate(x => x.Crop(rectangle));
await print.SaveAsPngAsync(tempPath);
if (ScreenshotHelper.HasTXt(path))
ScreenshotHelper.CopyTXt(path, tempPath);
@@ -218,6 +214,18 @@ namespace VRCX
return true;
}
public bool CropPrint(ref Image image)
{
if (image.Width != 2048 || image.Height != 1440)
return false;
var point = new Point(64, 69);
var size = new Size(1920, 1080);
var rectangle = new Rectangle(point, size);
image.Mutate(x => x.Crop(rectangle));
return true;
}
public async Task<string> SavePrintToFile(string url, string ugcFolderPath, string monthFolder, string fileName)
{
var folder = Path.Join(GetUGCPhotoLocation(ugcFolderPath), "Prints", MakeValidFileName(monthFolder));

View File

@@ -11,6 +11,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Cookie = System.Net.Cookie;
using NLog;
using SixLabors.ImageSharp;
using Timer = System.Threading.Timer;
#if !LINUX
@@ -342,6 +343,19 @@ namespace VRCX
private static async Task PrintImageUpload(HttpWebRequest request, IDictionary<string, object> options)
{
if (options.TryGetValue("cropWhiteBorder", out var cropWhiteBorder) && (bool)cropWhiteBorder)
{
var oldImageData = options["imageData"] as string;
var ms = new MemoryStream(Convert.FromBase64String(oldImageData));
var print = await Image.LoadAsync(ms);
if (Program.AppApiInstance.CropPrint(ref print))
{
var ms2 = new MemoryStream();
await print.SaveAsPngAsync(ms2);
options["imageData"] = Convert.ToBase64String(ms2.ToArray());
}
}
if (ProxySet)
request.Proxy = Proxy;

View File

@@ -1077,6 +1077,7 @@ console.log(`isLinux: ${LINUX}`);
if (!json.$fetchedAt) {
ref.$fetchedAt = new Date().toJSON();
}
ref.$disabledContentSettings = [];
if (json.contentSettings && Object.keys(json.contentSettings).length) {
for (var setting in $app.instanceContentSettings) {
if (json.contentSettings[setting]) {
@@ -16432,6 +16433,7 @@ console.log(`isLinux: ${LINUX}`);
});
$app.data.printUploadNote = '';
$app.data.printCropBorder = true;
$app.methods.onFileChangePrint = function (e) {
var clearFile = function () {
@@ -16472,13 +16474,16 @@ console.log(`isLinux: ${LINUX}`);
timestamp
};
var base64Body = btoa(r.result);
vrcPlusImageRequest.uploadPrint(base64Body, params).then((args) => {
$app.$message({
message: $t('message.print.uploaded'),
type: 'success'
var cropWhiteBorder = $app.printCropBorder;
vrcPlusImageRequest
.uploadPrint(base64Body, cropWhiteBorder, params)
.then((args) => {
$app.$message({
message: $t('message.print.uploaded'),
type: 'success'
});
return args;
});
return args;
});
};
r.readAsBinaryString(files[0]);
clearFile();

View File

@@ -61,9 +61,10 @@ const vrcPlusImageReq = {
});
},
uploadPrint(imageData, params) {
uploadPrint(imageData, cropWhiteBorder, params) {
return window.API.call('prints', {
uploadImagePrint: true,
cropWhiteBorder,
postData: JSON.stringify(params),
imageData
}).then((json) => {

View File

@@ -210,7 +210,7 @@ export default class extends baseClass {
'<span><span style="color:#67c23a">Android: </span>{{ platforms.android }}</span></br>' +
'<span>{{ $t("dialog.user.info.instance_game_version") }} {{ gameServerVersion }}</span></br>' +
'<span v-if="queueEnabled">{{ $t("dialog.user.info.instance_queuing_enabled") }}</br></span>' +
'<span v-if="disabledContentSettings">{{ $t("dialog.user.info.instance_disabled_content_settings") }} {{ disabledContentSettings }}</br></span>' +
'<span v-if="disabledContentSettings">{{ $t("dialog.user.info.instance_disabled_content") }} {{ disabledContentSettings }}</br></span>' +
'<span v-if="userList.length">{{ $t("dialog.user.info.instance_users") }}</br></span>' +
'<template v-for="user in userList"><span style="cursor:pointer;margin-right:5px" @click="showUserDialog(user.id)" v-text="user.displayName"></span></template>' +
'</div>' +

View File

@@ -749,7 +749,7 @@
"instance_game_version": "Game Version:",
"last_join": "Last Join:",
"instance_queuing_enabled": "Queuing Enabled",
"instance_disabled_content_settings": "Disabled Content Settings:",
"instance_disabled_content": "Disabled Content:",
"instance_creator": "Instance Creator",
"note": "Note",
"note_placeholder": "Click to add a note",
@@ -1434,7 +1434,8 @@
"emoji_animation_frame_count": "Frame Count:",
"emoji_loop_pingpong": "Loop PingPong",
"flipbook_info": "Select a 1024x1024 PNG spritesheet to use as an animated emoji, available frame grid sizes: 4, 16 or 64 (max FPS 64, max frames 64)",
"note": "Note"
"note": "Note",
"crop_print_border": "Crop Print Border"
},
"change_content_image": {
"avatar": "Change Avatar Image",

View File

@@ -399,6 +399,8 @@ mixin currentUser
maxlength='32'
style='margin-left: 10px; width: 300px'
:placeholder='$t("dialog.gallery_icons.note")')
el-checkbox(v-model='printCropBorder' style='margin-left: 10px; margin-right: 10px')
span {{ $t('dialog.gallery_icons.crop_print_border') }}
br
.x-friend-item(
v-for='image in printTable'

View File

@@ -140,7 +140,7 @@ mixin userDialog
size='mini'
style='margin-right: 5px; margin-top: 5px') {{ userDialog.ref.last_platform }}
el-tag.x-tag-age-verification(
v-if='userDialog.ref.ageVerificationStatus && userDialog.ref.ageVerificationStatus !== "hidden"'
v-if='userDialog.ref.ageVerified || userDialog.ref.ageVerificationStatus !== "hidden"'
type='info'
effect='plain'
size='mini'