Merge pull request #2313 from devLotto/screenshot-improvements

screenshotplugin: stretch timestamp in stretched fixed mode
This commit is contained in:
Adam
2018-05-04 17:23:32 -04:00
committed by GitHub
3 changed files with 168 additions and 51 deletions

View File

@@ -60,7 +60,7 @@ public class ScreenshotInput implements KeyListener
if (event.getKeyCode() == KeyEvent.VK_INSERT)
{
plugin.takeScreenshot(TIME_FORMAT.format(new Date()), config.displayDate());
plugin.takeScreenshot(TIME_FORMAT.format(new Date()));
}
}

View File

@@ -0,0 +1,140 @@
/*
* Copyright (c) 2018, Lotto <https://github.com/devLotto>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package net.runelite.client.plugins.screenshot;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Consumer;
import javax.imageio.ImageIO;
import javax.inject.Inject;
import lombok.extern.slf4j.Slf4j;
import net.runelite.api.Client;
import net.runelite.api.MainBufferProvider;
import net.runelite.client.ui.DrawManager;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.ui.overlay.OverlayLayer;
import net.runelite.client.ui.overlay.OverlayPosition;
import net.runelite.client.ui.overlay.OverlayPriority;
@Slf4j
public class ScreenshotOverlay extends Overlay
{
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MMM. dd, yyyy", Locale.US);
private static final int REPORT_BUTTON_X_OFFSET = 404;
private static BufferedImage REPORT_BUTTON;
static
{
try
{
synchronized (ImageIO.class)
{
REPORT_BUTTON = ImageIO.read(ScreenshotPlugin.class.getResourceAsStream("report_button.png"));
}
}
catch (IOException e)
{
log.warn("Report button image failed to load", e);
}
}
private final Client client;
private final DrawManager drawManager;
private final Queue<Consumer<BufferedImage>> consumers = new ConcurrentLinkedQueue<>();
@Inject
public ScreenshotOverlay(Client client, DrawManager drawManager)
{
setPosition(OverlayPosition.DYNAMIC);
setPriority(OverlayPriority.HIGH);
setLayer(OverlayLayer.ABOVE_WIDGETS);
this.client = client;
this.drawManager = drawManager;
}
@Override
public Dimension render(Graphics2D graphics)
{
if (consumers.isEmpty())
{
return null;
}
final MainBufferProvider bufferProvider = (MainBufferProvider) client.getBufferProvider();
final int imageHeight = ((BufferedImage) bufferProvider.getImage()).getHeight();
final int y = imageHeight - REPORT_BUTTON.getHeight() - 1;
graphics.drawImage(REPORT_BUTTON, REPORT_BUTTON_X_OFFSET, y, null);
graphics.setFont(FontManager.getRunescapeSmallFont());
FontMetrics fontMetrics = graphics.getFontMetrics();
String date = DATE_FORMAT.format(new Date());
final int dateWidth = fontMetrics.stringWidth(date);
final int dateHeight = fontMetrics.getHeight();
final int textX = REPORT_BUTTON_X_OFFSET + REPORT_BUTTON.getWidth() / 2 - dateWidth / 2;
final int textY = y + REPORT_BUTTON.getHeight() / 2 + dateHeight / 2;
graphics.setColor(Color.BLACK);
graphics.drawString(date, textX + 1, textY + 1);
graphics.setColor(Color.WHITE);
graphics.drawString(date, textX, textY);
// Request the queued screenshots to be taken,
// now that the timestamp is visible.
Consumer<BufferedImage> consumer;
while ((consumer = consumers.poll()) != null)
{
drawManager.requestNextFrameListener(consumer);
}
return null;
}
public void queueForTimestamp(Consumer<BufferedImage> screenshotConsumer)
{
if (REPORT_BUTTON == null)
{
return;
}
consumers.add(screenshotConsumer);
}
}

View File

@@ -28,9 +28,7 @@ import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMap;
import com.google.common.eventbus.Subscribe;
import com.google.inject.Provides;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.TrayIcon;
@@ -47,6 +45,7 @@ import java.time.LocalDate;
import java.util.Date;
import java.util.Locale;
import java.util.concurrent.ScheduledExecutorService;
import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.imageio.ImageIO;
@@ -79,9 +78,9 @@ import net.runelite.client.plugins.PluginDescriptor;
import net.runelite.client.plugins.screenshot.imgur.ImageUploadRequest;
import net.runelite.client.plugins.screenshot.imgur.ImageUploadResponse;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.FontManager;
import net.runelite.client.ui.NavigationButton;
import net.runelite.client.ui.TitleToolbar;
import net.runelite.client.ui.overlay.Overlay;
import net.runelite.client.util.Text;
import net.runelite.http.api.RuneLiteAPI;
import okhttp3.Call;
@@ -102,7 +101,6 @@ public class ScreenshotPlugin extends Plugin
private static final HttpUrl IMGUR_IMAGE_UPLOAD_URL = HttpUrl.parse("https://api.imgur.com/3/image");
private static final MediaType JSON = MediaType.parse("application/json");
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("MMM. dd, yyyy", Locale.US);
static final DateFormat TIME_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US);
private static final Pattern NUMBER_PATTERN = Pattern.compile("([0-9]+)");
@@ -118,6 +116,9 @@ public class ScreenshotPlugin extends Plugin
@Inject
private ScreenshotConfig config;
@Inject
private ScreenshotOverlay screenshotOverlay;
@Inject
private Notifier notifier;
@@ -150,6 +151,12 @@ public class ScreenshotPlugin extends Plugin
return configManager.getConfig(ScreenshotConfig.class);
}
@Override
public Overlay getOverlay()
{
return screenshotOverlay;
}
@Override
protected void startUp() throws Exception
{
@@ -167,9 +174,7 @@ public class ScreenshotPlugin extends Plugin
titleBarButton = NavigationButton.builder()
.tooltip("Take screenshot")
.icon(iconImage)
.onClick(() -> takeScreenshot(
TIME_FORMAT.format(new Date()),
client.getLocalPlayer() != null))
.onClick(() -> takeScreenshot(TIME_FORMAT.format(new Date())))
.popup(ImmutableMap
.<String, Runnable>builder()
.put("Open screenshot folder...", () ->
@@ -254,7 +259,7 @@ public class ScreenshotPlugin extends Plugin
if (event.getGroupId() == WidgetID.KINGDOM_GROUP_ID)
{
String fileName = "Kingdom " + LocalDate.now();
takeScreenshot(fileName, config.displayDate());
takeScreenshot(fileName);
}
}
@@ -271,6 +276,7 @@ public class ScreenshotPlugin extends Plugin
switch (TO_GROUP(widget.getId()))
{
case LEVEL_UP_GROUP_ID:
case DIALOG_SPRITE_GROUP_ID:
if (!config.screenshotLevels())
{
return;
@@ -359,7 +365,7 @@ public class ScreenshotPlugin extends Plugin
return;
}
takeScreenshot(fileName, config.displayDate());
takeScreenshot(fileName);
}
/**
@@ -394,9 +400,8 @@ public class ScreenshotPlugin extends Plugin
* and optionally uploads it to an image-hosting service.
*
* @param fileName Filename to use, without file extension.
* @param displayDate Whether to show today's date on the report button as the screenshot is taken.
*/
void takeScreenshot(String fileName, boolean displayDate)
void takeScreenshot(String fileName)
{
if (client.getGameState() == GameState.LOGIN_SCREEN)
{
@@ -405,7 +410,7 @@ public class ScreenshotPlugin extends Plugin
return;
}
drawManager.requestNextFrameListener(image ->
Consumer<BufferedImage> screenshotConsumer = image ->
{
BufferedImage screenshot = config.includeFrame()
? new BufferedImage(clientUi.getWidth(), clientUi.getHeight(), BufferedImage.TYPE_INT_ARGB)
@@ -430,43 +435,6 @@ public class ScreenshotPlugin extends Plugin
// Draw the game onto the screenshot
graphics.drawImage(image, gameOffsetX, gameOffsetY, null);
if (displayDate)
{
try (InputStream reportButton = ScreenshotPlugin.class.getResourceAsStream("report_button.png"))
{
BufferedImage reportButtonImage;
synchronized (ImageIO.class)
{
reportButtonImage = ImageIO.read(reportButton);
}
int x = gameOffsetX + 403;
int y = gameOffsetY + image.getHeight() - reportButtonImage.getHeight() - 1;
graphics.drawImage(reportButtonImage, x, y, null);
graphics.setFont(FontManager.getRunescapeSmallFont());
FontMetrics fontMetrics = graphics.getFontMetrics();
String date = DATE_FORMAT.format(new Date());
int dateWidth = fontMetrics.stringWidth(date);
int dateHeight = fontMetrics.getHeight();
int textX = x + reportButtonImage.getWidth() / 2 - dateWidth / 2;
int textY = y + reportButtonImage.getHeight() / 2 + dateHeight / 2;
graphics.setColor(Color.BLACK);
graphics.drawString(date, textX + 1, textY + 1);
graphics.setColor(Color.WHITE);
graphics.drawString(date, textX, textY);
}
catch (Exception ex)
{
log.warn("error displaying date on screenshot", ex);
}
}
File playerFolder;
if (client.getLocalPlayer() != null && client.getLocalPlayer().getName() != null)
{
@@ -501,7 +469,16 @@ public class ScreenshotPlugin extends Plugin
log.warn("error writing screenshot", ex);
}
});
});
};
if (config.displayDate())
{
screenshotOverlay.queueForTimestamp(screenshotConsumer);
}
else
{
drawManager.requestNextFrameListener(screenshotConsumer);
}
}
/**