From 9ed93ad2eb9ead9d7fc13abf61b233e1e42742e7 Mon Sep 17 00:00:00 2001 From: Natsumi Date: Fri, 14 Mar 2025 06:56:24 +1300 Subject: [PATCH] Crop print border on upload --- Dotnet/AppApi/Common/ImageSaving.cs | 20 ++++++++++++++------ Dotnet/WebApi.cs | 14 ++++++++++++++ src/app.js | 17 +++++++++++------ src/classes/request/vrcPlusImage.js | 3 ++- src/classes/uiComponents.js | 2 +- src/localization/en/en.json | 5 +++-- src/mixins/dialogs/currentUser.pug | 2 ++ src/mixins/dialogs/userDialog.pug | 2 +- 8 files changed, 48 insertions(+), 17 deletions(-) diff --git a/Dotnet/AppApi/Common/ImageSaving.cs b/Dotnet/AppApi/Common/ImageSaving.cs index 962f2dd8..7c49412b 100644 --- a/Dotnet/AppApi/Common/ImageSaving.cs +++ b/Dotnet/AppApi/Common/ImageSaving.cs @@ -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 SavePrintToFile(string url, string ugcFolderPath, string monthFolder, string fileName) { var folder = Path.Join(GetUGCPhotoLocation(ugcFolderPath), "Prints", MakeValidFileName(monthFolder)); diff --git a/Dotnet/WebApi.cs b/Dotnet/WebApi.cs index c93579be..e97e1ed0 100644 --- a/Dotnet/WebApi.cs +++ b/Dotnet/WebApi.cs @@ -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 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; diff --git a/src/app.js b/src/app.js index 2124b08b..a708afdb 100644 --- a/src/app.js +++ b/src/app.js @@ -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(); diff --git a/src/classes/request/vrcPlusImage.js b/src/classes/request/vrcPlusImage.js index bf5fef52..ad08429e 100644 --- a/src/classes/request/vrcPlusImage.js +++ b/src/classes/request/vrcPlusImage.js @@ -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) => { diff --git a/src/classes/uiComponents.js b/src/classes/uiComponents.js index 89aba5db..ee071fd4 100644 --- a/src/classes/uiComponents.js +++ b/src/classes/uiComponents.js @@ -210,7 +210,7 @@ export default class extends baseClass { 'Android: {{ platforms.android }}
' + '{{ $t("dialog.user.info.instance_game_version") }} {{ gameServerVersion }}
' + '{{ $t("dialog.user.info.instance_queuing_enabled") }}
' + - '{{ $t("dialog.user.info.instance_disabled_content_settings") }} {{ disabledContentSettings }}
' + + '{{ $t("dialog.user.info.instance_disabled_content") }} {{ disabledContentSettings }}
' + '{{ $t("dialog.user.info.instance_users") }}
' + '' + '' + diff --git a/src/localization/en/en.json b/src/localization/en/en.json index e2f94aad..6cf739a3 100644 --- a/src/localization/en/en.json +++ b/src/localization/en/en.json @@ -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", diff --git a/src/mixins/dialogs/currentUser.pug b/src/mixins/dialogs/currentUser.pug index b088f775..fd74e582 100644 --- a/src/mixins/dialogs/currentUser.pug +++ b/src/mixins/dialogs/currentUser.pug @@ -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' diff --git a/src/mixins/dialogs/userDialog.pug b/src/mixins/dialogs/userDialog.pug index 1684cd4b..050049d2 100644 --- a/src/mixins/dialogs/userDialog.pug +++ b/src/mixins/dialogs/userDialog.pug @@ -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'