mirror of
https://github.com/ppy/osu.git
synced 2025-02-14 22:43:05 +08:00
Merge pull request #26697 from LeNitrous/add/scaled-screenshot
Crop screenshots to scaling container
This commit is contained in:
commit
45b4edcd23
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
@ -24,6 +22,8 @@ using osu.Game.Overlays;
|
|||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
using SixLabors.ImageSharp;
|
using SixLabors.ImageSharp;
|
||||||
using SixLabors.ImageSharp.Formats.Jpeg;
|
using SixLabors.ImageSharp.Formats.Jpeg;
|
||||||
|
using SixLabors.ImageSharp.PixelFormats;
|
||||||
|
using SixLabors.ImageSharp.Processing;
|
||||||
|
|
||||||
namespace osu.Game.Graphics
|
namespace osu.Game.Graphics
|
||||||
{
|
{
|
||||||
@ -37,30 +37,26 @@ namespace osu.Game.Graphics
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IBindable<bool> CursorVisibility => cursorVisibility;
|
public IBindable<bool> CursorVisibility => cursorVisibility;
|
||||||
|
|
||||||
private Bindable<ScreenshotFormat> screenshotFormat;
|
[Resolved]
|
||||||
private Bindable<bool> captureMenuCursor;
|
private GameHost host { get; set; } = null!;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private GameHost host { get; set; }
|
private Clipboard clipboard { get; set; } = null!;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private Clipboard clipboard { get; set; }
|
private INotificationOverlay notificationOverlay { get; set; } = null!;
|
||||||
|
|
||||||
private Storage storage;
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private INotificationOverlay notificationOverlay { get; set; }
|
private OsuConfigManager config { get; set; } = null!;
|
||||||
|
|
||||||
private Sample shutter;
|
private Storage storage = null!;
|
||||||
|
|
||||||
|
private Sample? shutter;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config, Storage storage, AudioManager audio)
|
private void load(Storage storage, AudioManager audio)
|
||||||
{
|
{
|
||||||
this.storage = storage.GetStorageForDirectory(@"screenshots");
|
this.storage = storage.GetStorageForDirectory(@"screenshots");
|
||||||
|
|
||||||
screenshotFormat = config.GetBindable<ScreenshotFormat>(OsuSetting.ScreenshotFormat);
|
|
||||||
captureMenuCursor = config.GetBindable<bool>(OsuSetting.ScreenshotCaptureMenuCursor);
|
|
||||||
|
|
||||||
shutter = audio.Samples.Get("UI/shutter");
|
shutter = audio.Samples.Get("UI/shutter");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +68,7 @@ namespace osu.Game.Graphics
|
|||||||
switch (e.Action)
|
switch (e.Action)
|
||||||
{
|
{
|
||||||
case GlobalAction.TakeScreenshot:
|
case GlobalAction.TakeScreenshot:
|
||||||
shutter.Play();
|
shutter?.Play();
|
||||||
TakeScreenshotAsync().FireAndForget();
|
TakeScreenshotAsync().FireAndForget();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -90,9 +86,12 @@ namespace osu.Game.Graphics
|
|||||||
{
|
{
|
||||||
Interlocked.Increment(ref screenShotTasks);
|
Interlocked.Increment(ref screenShotTasks);
|
||||||
|
|
||||||
|
ScreenshotFormat screenshotFormat = config.Get<ScreenshotFormat>(OsuSetting.ScreenshotFormat);
|
||||||
|
bool captureMenuCursor = config.Get<bool>(OsuSetting.ScreenshotCaptureMenuCursor);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!captureMenuCursor.Value)
|
if (!captureMenuCursor)
|
||||||
{
|
{
|
||||||
cursorVisibility.Value = false;
|
cursorVisibility.Value = false;
|
||||||
|
|
||||||
@ -101,7 +100,7 @@ namespace osu.Game.Graphics
|
|||||||
|
|
||||||
int framesWaited = 0;
|
int framesWaited = 0;
|
||||||
|
|
||||||
using (var framesWaitedEvent = new ManualResetEventSlim(false))
|
using (ManualResetEventSlim framesWaitedEvent = new ManualResetEventSlim(false))
|
||||||
{
|
{
|
||||||
ScheduledDelegate waitDelegate = host.DrawThread.Scheduler.AddDelayed(() =>
|
ScheduledDelegate waitDelegate = host.DrawThread.Scheduler.AddDelayed(() =>
|
||||||
{
|
{
|
||||||
@ -117,17 +116,41 @@ namespace osu.Game.Graphics
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var image = await host.TakeScreenshotAsync().ConfigureAwait(false))
|
using (Image<Rgba32>? image = await host.TakeScreenshotAsync().ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
|
if (config.Get<ScalingMode>(OsuSetting.Scaling) == ScalingMode.Everything)
|
||||||
|
{
|
||||||
|
float posX = config.Get<float>(OsuSetting.ScalingPositionX);
|
||||||
|
float posY = config.Get<float>(OsuSetting.ScalingPositionY);
|
||||||
|
float sizeX = config.Get<float>(OsuSetting.ScalingSizeX);
|
||||||
|
float sizeY = config.Get<float>(OsuSetting.ScalingSizeY);
|
||||||
|
|
||||||
|
image.Mutate(m =>
|
||||||
|
{
|
||||||
|
Rectangle rect = new Rectangle(Point.Empty, m.GetCurrentSize());
|
||||||
|
|
||||||
|
// Reduce size by user scale settings...
|
||||||
|
int sx = (rect.Width - (int)(rect.Width * sizeX)) / 2;
|
||||||
|
int sy = (rect.Height - (int)(rect.Height * sizeY)) / 2;
|
||||||
|
rect.Inflate(-sx, -sy);
|
||||||
|
|
||||||
|
// ...then adjust the region based on their positional offset.
|
||||||
|
rect.X = (int)(rect.X * posX) * 2;
|
||||||
|
rect.Y = (int)(rect.Y * posY) * 2;
|
||||||
|
|
||||||
|
m.Crop(rect);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
clipboard.SetImage(image);
|
clipboard.SetImage(image);
|
||||||
|
|
||||||
(string filename, var stream) = getWritableStream();
|
(string? filename, Stream? stream) = getWritableStream(screenshotFormat);
|
||||||
|
|
||||||
if (filename == null) return;
|
if (filename == null) return;
|
||||||
|
|
||||||
using (stream)
|
using (stream)
|
||||||
{
|
{
|
||||||
switch (screenshotFormat.Value)
|
switch (screenshotFormat)
|
||||||
{
|
{
|
||||||
case ScreenshotFormat.Png:
|
case ScreenshotFormat.Png:
|
||||||
await image.SaveAsPngAsync(stream).ConfigureAwait(false);
|
await image.SaveAsPngAsync(stream).ConfigureAwait(false);
|
||||||
@ -140,7 +163,7 @@ namespace osu.Game.Graphics
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new InvalidOperationException($"Unknown enum member {nameof(ScreenshotFormat)} {screenshotFormat.Value}.");
|
throw new InvalidOperationException($"Unknown enum member {nameof(ScreenshotFormat)} {screenshotFormat}.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,12 +187,12 @@ namespace osu.Game.Graphics
|
|||||||
|
|
||||||
private static readonly object filename_reservation_lock = new object();
|
private static readonly object filename_reservation_lock = new object();
|
||||||
|
|
||||||
private (string filename, Stream stream) getWritableStream()
|
private (string? filename, Stream? stream) getWritableStream(ScreenshotFormat format)
|
||||||
{
|
{
|
||||||
lock (filename_reservation_lock)
|
lock (filename_reservation_lock)
|
||||||
{
|
{
|
||||||
var dt = DateTime.Now;
|
DateTime dt = DateTime.Now;
|
||||||
string fileExt = screenshotFormat.ToString().ToLowerInvariant();
|
string fileExt = format.ToString().ToLowerInvariant();
|
||||||
|
|
||||||
string withoutIndex = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}.{fileExt}";
|
string withoutIndex = $"osu_{dt:yyyy-MM-dd_HH-mm-ss}.{fileExt}";
|
||||||
if (!storage.Exists(withoutIndex))
|
if (!storage.Exists(withoutIndex))
|
||||||
|
Loading…
Reference in New Issue
Block a user