Split off image generation to separate project (#2395)

With the approaching games, PKM sprites are a different size from the 3DS era (as already hinted by LGPE, which has 56x68). It'll be a little easier to manage with this portion of the library walled off from the rest of the codebase.

Eventually the net46 target will use fody or something to merge in these extra dependency dll's automatically to not disturb the usual exe/dll experience.
This commit is contained in:
Kurt 2019-09-29 09:47:06 -07:00 committed by GitHub
parent 7db0657711
commit 94baab1c45
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3055 changed files with 39292 additions and 43654 deletions

View file

@ -38,7 +38,7 @@ namespace PKHeX.Core
if (pkm is PK7 pk7)
{
byte[] payload = QR7.GenerateQRData(pk7);
return string.Concat(payload.Select(z => (char)z));
return GetMessage(payload);
}
var server = GetExploitURLPrefixPKM(pkm.Format);
@ -46,6 +46,13 @@ namespace PKHeX.Core
return GetMessageBase64(data, server);
}
/// <summary>
/// Gets a QR Message from the input <see cref="byte"/> data.
/// </summary>
/// <param name="payload">Data to encode</param>
/// <returns>QR Message</returns>
public static string GetMessage(byte[] payload) => string.Concat(payload.Select(z => (char) z));
/// <summary>
/// Gets a QR Message from the input <see cref="MysteryGift"/> data.
/// </summary>

View file

@ -1,16 +1,13 @@
using System;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text.RegularExpressions;
namespace PKHeX.WinForms
namespace PKHeX.Core
{
public static class NetUtil
{
private static readonly Regex LatestGitTagRegex = new Regex("\\\"tag_name\"\\s*\\:\\s*\\\"([0-9]+\\.[0-9]+\\.[0-9]+)\\\""); // Match `"tag_name": "18.12.02"`. Group 1 is `18.12.02`
public static string GetStringFromURL(string webURL)
{
try
@ -37,19 +34,7 @@ namespace PKHeX.WinForms
return httpWebResponse.GetResponseStream();
}
public static Image GetImageFromURL(string webURL)
{
try
{
var stream = GetStreamFromURL(webURL);
return stream != null ? Image.FromStream(stream) : null;
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
return null;
}
}
private static readonly Regex LatestGitTagRegex = new Regex("\\\"tag_name\"\\s*\\:\\s*\\\"([0-9]+\\.[0-9]+\\.[0-9]+)\\\""); // Match `"tag_name": "18.12.02"`. Group 1 is `18.12.02`
/// <summary>
/// Gets the latest version of PKHeX according to the Github API

View file

@ -3,7 +3,7 @@ using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace PKHeX.WinForms
namespace PKHeX.Drawing
{
/// <summary>
/// Image Layering/Blending Utility

View file

@ -0,0 +1,40 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>netcoreapp3.0;net46</TargetFrameworks>
<LangVersion>8</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="QRCoder" Version="1.3.6" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PKHeX.Core\PKHeX.Core.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
<PackageReference Include="System.Drawing.Common">
<Version>4.6.0</Version>
</PackageReference>
<PackageReference Include="System.Resources.Extensions">
<Version>4.6.0</Version>
</PackageReference>
</ItemGroup>
</Project>

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,101 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using PKHeX.Core;
namespace PKHeX.Drawing
{
public static class QRDecode
{
// QR Utility
private const string DecodeAPI = "http://api.qrserver.com/v1/read-qr-code/?fileurl=";
public static QRDecodeMsg GetQRData(string address, out byte[] result)
{
result = Array.Empty<byte>();
// Fetch data from QR code...
if (!address.StartsWith("http"))
return QRDecodeMsg.BadPath;
string webURL = DecodeAPI + WebUtility.UrlEncode(address);
string data;
try
{
data = NetUtil.GetStringFromURL(webURL);
if (data.Contains("could not find"))
return QRDecodeMsg.BadImage;
if (data.Contains("filetype not supported"))
return QRDecodeMsg.BadType;
}
catch { return QRDecodeMsg.BadConnection; }
// Quickly convert the json response to a data string
try
{
result = DecodeQRJson(data);
return QRDecodeMsg.Success;
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
return QRDecodeMsg.BadConversion;
}
}
private static byte[] DecodeQRJson(string data)
{
const string cap = "\",\"error\":null}]}]";
const string intro = "[{\"type\":\"qrcode\",\"symbol\":[{\"seq\":0,\"data\":\"";
const string qrcode = "nQR-Code:";
if (!data.StartsWith(intro))
throw new FormatException();
string pkstr = data.Substring(intro.Length);
if (pkstr.Contains(qrcode)) // Remove multiple QR codes in same image
pkstr = pkstr.Substring(0, pkstr.IndexOf(qrcode, StringComparison.Ordinal));
pkstr = pkstr.Substring(0, pkstr.IndexOf(cap, StringComparison.Ordinal)); // Trim outro
if (!pkstr.StartsWith("http") && !pkstr.StartsWith("null")) // G7
{
string fstr = Regex.Unescape(pkstr);
byte[] raw = Encoding.Unicode.GetBytes(fstr);
// Remove 00 interstitials and retrieve from offset 0x30, take PK7 Stored Size (always)
return raw.Where((_, i) => i % 2 == 0).Skip(0x30).Take(0xE8).ToArray();
}
// All except G7
pkstr = pkstr.Substring(pkstr.IndexOf('#') + 1); // Trim URL
pkstr = pkstr.Replace("\\", string.Empty); // Rectify response
return Convert.FromBase64String(pkstr);
}
public static string ConvertMsg(this QRDecodeMsg msg)
{
return msg switch
{
QRDecodeMsg.Success => string.Empty,
QRDecodeMsg.BadPath => MessageStrings.MsgQRUrlFailPath,
QRDecodeMsg.BadImage => MessageStrings.MsgQRUrlFailImage,
QRDecodeMsg.BadType => MessageStrings.MsgQRUrlFailType,
QRDecodeMsg.BadConnection => MessageStrings.MsgQRUrlFailConnection,
QRDecodeMsg.BadConversion => MessageStrings.MsgQRUrlFailConvert,
_ => throw new ArgumentOutOfRangeException(nameof(msg), msg, null)
};
}
}
public enum QRDecodeMsg
{
Success,
BadPath,
BadImage,
BadType,
BadConnection,
BadConversion,
}
}

View file

@ -0,0 +1,27 @@
using System.Drawing;
using PKHeX.Core;
using QRCoder;
namespace PKHeX.Drawing
{
public static class QREncode
{
public static Image GenerateQRCode(MysteryGift mg) => GenerateQRCode(QRMessageUtil.GetMessage(mg));
public static Image GenerateQRCode(PKM pkm) => GenerateQRCode(QRMessageUtil.GetMessage(pkm));
public static Image GenerateQRCode7(PK7 pk7, int box = 0, int slot = 0, int num_copies = 1)
{
byte[] data = QR7.GenerateQRData(pk7, box, slot, num_copies);
var msg = QRMessageUtil.GetMessage(data);
return GenerateQRCode(msg, ppm: 4);
}
private static Image GenerateQRCode(string msg, int ppm = 4)
{
using var generator = new QRCodeGenerator();
using var qr_data = generator.CreateQrCode(msg, QRCodeGenerator.ECCLevel.Q);
using var qr_code = new QRCode(qr_data);
return qr_code.GetGraphic(ppm);
}
}
}

View file

@ -0,0 +1,53 @@
using System;
using System.Drawing;
namespace PKHeX.Drawing
{
public static class QRImageUtil
{
public static Bitmap GetQRImage(Image qr, Image pkm)
{
// create a small area with the pkm sprite, with a white background
var foreground = new Bitmap(45, 45);
using (Graphics gfx = Graphics.FromImage(foreground))
{
gfx.FillRectangle(new SolidBrush(Color.White), 0, 0, foreground.Width, foreground.Height);
int x = (foreground.Width / 2) - (pkm.Width / 2);
int y = (foreground.Height / 2) - (pkm.Height / 2);
gfx.DrawImage(pkm, x, y);
}
// Layer on Preview Image
{
int x = (qr.Width / 2) - (foreground.Width / 2);
int y = (qr.Height / 2) - (foreground.Height / 2);
return ImageUtil.LayerImage(qr, foreground, x, y);
}
}
public static Bitmap GetQRImageExtended(Font font, Image qr, Image pkm, int width, int height, string[] lines, string extraText)
{
var pic = GetQRImage(qr, pkm);
return ExtendImage(font, qr, width, height, pic, lines, extraText);
}
private static Bitmap ExtendImage(Font font, Image qr, int width, int height, Image pic, string[] lines, string extraText)
{
var newpic = new Bitmap(width, height);
using (Graphics g = Graphics.FromImage(newpic))
{
g.FillRectangle(new SolidBrush(Color.White), 0, 0, newpic.Width, newpic.Height);
g.DrawImage(pic, 0, 0);
g.DrawString(GetLine(lines, 0), font, Brushes.Black, new PointF(18, qr.Height - 5));
g.DrawString(GetLine(lines, 1), font, Brushes.Black, new PointF(18, qr.Height + 8));
g.DrawString(GetLine(lines, 2).Replace(Environment.NewLine, "/").Replace("//", " ").Replace(":/", ": "), font,
Brushes.Black, new PointF(18, qr.Height + 20));
g.DrawString(GetLine(lines, 3) + extraText, font, Brushes.Black, new PointF(18, qr.Height + 32));
}
return newpic;
}
private static string GetLine(string[] lines, int line) => lines.Length <= line ? string.Empty : lines[line];
}
}

View file

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

Before

Width:  |  Height:  |  Size: 393 B

After

Width:  |  Height:  |  Size: 393 B

View file

Before

Width:  |  Height:  |  Size: 772 B

After

Width:  |  Height:  |  Size: 772 B

View file

Before

Width:  |  Height:  |  Size: 848 B

After

Width:  |  Height:  |  Size: 848 B

View file

Before

Width:  |  Height:  |  Size: 845 B

After

Width:  |  Height:  |  Size: 845 B

View file

Before

Width:  |  Height:  |  Size: 831 B

After

Width:  |  Height:  |  Size: 831 B

View file

Before

Width:  |  Height:  |  Size: 874 B

After

Width:  |  Height:  |  Size: 874 B

View file

Before

Width:  |  Height:  |  Size: 874 B

After

Width:  |  Height:  |  Size: 874 B

View file

Before

Width:  |  Height:  |  Size: 226 B

After

Width:  |  Height:  |  Size: 226 B

View file

Before

Width:  |  Height:  |  Size: 304 B

After

Width:  |  Height:  |  Size: 304 B

View file

Before

Width:  |  Height:  |  Size: 790 B

After

Width:  |  Height:  |  Size: 790 B

View file

Before

Width:  |  Height:  |  Size: 555 B

After

Width:  |  Height:  |  Size: 555 B

View file

Before

Width:  |  Height:  |  Size: 151 B

After

Width:  |  Height:  |  Size: 151 B

View file

Before

Width:  |  Height:  |  Size: 407 B

After

Width:  |  Height:  |  Size: 407 B

View file

Before

Width:  |  Height:  |  Size: 351 B

After

Width:  |  Height:  |  Size: 351 B

View file

Before

Width:  |  Height:  |  Size: 308 B

After

Width:  |  Height:  |  Size: 308 B

View file

Before

Width:  |  Height:  |  Size: 327 B

After

Width:  |  Height:  |  Size: 327 B

View file

Before

Width:  |  Height:  |  Size: 434 B

After

Width:  |  Height:  |  Size: 434 B

View file

Before

Width:  |  Height:  |  Size: 503 B

After

Width:  |  Height:  |  Size: 503 B

View file

Before

Width:  |  Height:  |  Size: 474 B

After

Width:  |  Height:  |  Size: 474 B

View file

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 402 B

View file

Before

Width:  |  Height:  |  Size: 490 B

After

Width:  |  Height:  |  Size: 490 B

View file

Before

Width:  |  Height:  |  Size: 448 B

After

Width:  |  Height:  |  Size: 448 B

View file

Before

Width:  |  Height:  |  Size: 424 B

After

Width:  |  Height:  |  Size: 424 B

View file

Before

Width:  |  Height:  |  Size: 406 B

After

Width:  |  Height:  |  Size: 406 B

View file

Before

Width:  |  Height:  |  Size: 430 B

After

Width:  |  Height:  |  Size: 430 B

View file

Before

Width:  |  Height:  |  Size: 537 B

After

Width:  |  Height:  |  Size: 537 B

View file

Before

Width:  |  Height:  |  Size: 278 B

After

Width:  |  Height:  |  Size: 278 B

View file

Before

Width:  |  Height:  |  Size: 606 B

After

Width:  |  Height:  |  Size: 606 B

View file

Before

Width:  |  Height:  |  Size: 410 B

After

Width:  |  Height:  |  Size: 410 B

View file

Before

Width:  |  Height:  |  Size: 510 B

After

Width:  |  Height:  |  Size: 510 B

View file

Before

Width:  |  Height:  |  Size: 412 B

After

Width:  |  Height:  |  Size: 412 B

View file

Before

Width:  |  Height:  |  Size: 409 B

After

Width:  |  Height:  |  Size: 409 B

View file

Before

Width:  |  Height:  |  Size: 530 B

After

Width:  |  Height:  |  Size: 530 B

View file

Before

Width:  |  Height:  |  Size: 456 B

After

Width:  |  Height:  |  Size: 456 B

View file

Before

Width:  |  Height:  |  Size: 369 B

After

Width:  |  Height:  |  Size: 369 B

View file

Before

Width:  |  Height:  |  Size: 444 B

After

Width:  |  Height:  |  Size: 444 B

View file

Before

Width:  |  Height:  |  Size: 458 B

After

Width:  |  Height:  |  Size: 458 B

View file

Before

Width:  |  Height:  |  Size: 470 B

After

Width:  |  Height:  |  Size: 470 B

View file

Before

Width:  |  Height:  |  Size: 447 B

After

Width:  |  Height:  |  Size: 447 B

View file

Before

Width:  |  Height:  |  Size: 375 B

After

Width:  |  Height:  |  Size: 375 B

View file

Before

Width:  |  Height:  |  Size: 417 B

After

Width:  |  Height:  |  Size: 417 B

View file

Before

Width:  |  Height:  |  Size: 426 B

After

Width:  |  Height:  |  Size: 426 B

View file

Before

Width:  |  Height:  |  Size: 425 B

After

Width:  |  Height:  |  Size: 425 B

View file

Before

Width:  |  Height:  |  Size: 471 B

After

Width:  |  Height:  |  Size: 471 B

View file

Before

Width:  |  Height:  |  Size: 436 B

After

Width:  |  Height:  |  Size: 436 B

View file

Before

Width:  |  Height:  |  Size: 476 B

After

Width:  |  Height:  |  Size: 476 B

View file

Before

Width:  |  Height:  |  Size: 664 B

After

Width:  |  Height:  |  Size: 664 B

View file

Before

Width:  |  Height:  |  Size: 447 B

After

Width:  |  Height:  |  Size: 447 B

View file

Before

Width:  |  Height:  |  Size: 462 B

After

Width:  |  Height:  |  Size: 462 B

View file

Before

Width:  |  Height:  |  Size: 500 B

After

Width:  |  Height:  |  Size: 500 B

View file

Before

Width:  |  Height:  |  Size: 348 B

After

Width:  |  Height:  |  Size: 348 B

View file

Before

Width:  |  Height:  |  Size: 673 B

After

Width:  |  Height:  |  Size: 673 B

View file

Before

Width:  |  Height:  |  Size: 621 B

After

Width:  |  Height:  |  Size: 621 B

View file

Before

Width:  |  Height:  |  Size: 471 B

After

Width:  |  Height:  |  Size: 471 B

View file

Before

Width:  |  Height:  |  Size: 296 B

After

Width:  |  Height:  |  Size: 296 B

View file

Before

Width:  |  Height:  |  Size: 483 B

After

Width:  |  Height:  |  Size: 483 B

View file

Before

Width:  |  Height:  |  Size: 394 B

After

Width:  |  Height:  |  Size: 394 B

View file

Before

Width:  |  Height:  |  Size: 496 B

After

Width:  |  Height:  |  Size: 496 B

View file

Before

Width:  |  Height:  |  Size: 441 B

After

Width:  |  Height:  |  Size: 441 B

View file

Before

Width:  |  Height:  |  Size: 453 B

After

Width:  |  Height:  |  Size: 453 B

View file

Before

Width:  |  Height:  |  Size: 418 B

After

Width:  |  Height:  |  Size: 418 B

View file

Before

Width:  |  Height:  |  Size: 370 B

After

Width:  |  Height:  |  Size: 370 B

View file

Before

Width:  |  Height:  |  Size: 423 B

After

Width:  |  Height:  |  Size: 423 B

View file

Before

Width:  |  Height:  |  Size: 321 B

After

Width:  |  Height:  |  Size: 321 B

View file

Before

Width:  |  Height:  |  Size: 326 B

After

Width:  |  Height:  |  Size: 326 B

View file

Before

Width:  |  Height:  |  Size: 394 B

After

Width:  |  Height:  |  Size: 394 B

View file

Before

Width:  |  Height:  |  Size: 563 B

After

Width:  |  Height:  |  Size: 563 B

View file

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 477 B

View file

Before

Width:  |  Height:  |  Size: 499 B

After

Width:  |  Height:  |  Size: 499 B

View file

Before

Width:  |  Height:  |  Size: 441 B

After

Width:  |  Height:  |  Size: 441 B

View file

Before

Width:  |  Height:  |  Size: 466 B

After

Width:  |  Height:  |  Size: 466 B

View file

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 477 B

View file

Before

Width:  |  Height:  |  Size: 376 B

After

Width:  |  Height:  |  Size: 376 B

View file

Before

Width:  |  Height:  |  Size: 451 B

After

Width:  |  Height:  |  Size: 451 B

View file

Before

Width:  |  Height:  |  Size: 500 B

After

Width:  |  Height:  |  Size: 500 B

View file

Before

Width:  |  Height:  |  Size: 552 B

After

Width:  |  Height:  |  Size: 552 B

View file

Before

Width:  |  Height:  |  Size: 470 B

After

Width:  |  Height:  |  Size: 470 B

View file

Before

Width:  |  Height:  |  Size: 518 B

After

Width:  |  Height:  |  Size: 518 B

View file

Before

Width:  |  Height:  |  Size: 524 B

After

Width:  |  Height:  |  Size: 524 B

View file

Before

Width:  |  Height:  |  Size: 460 B

After

Width:  |  Height:  |  Size: 460 B

View file

Before

Width:  |  Height:  |  Size: 423 B

After

Width:  |  Height:  |  Size: 423 B

View file

Before

Width:  |  Height:  |  Size: 385 B

After

Width:  |  Height:  |  Size: 385 B

View file

Before

Width:  |  Height:  |  Size: 462 B

After

Width:  |  Height:  |  Size: 462 B

View file

Before

Width:  |  Height:  |  Size: 533 B

After

Width:  |  Height:  |  Size: 533 B

View file

Before

Width:  |  Height:  |  Size: 418 B

After

Width:  |  Height:  |  Size: 418 B

View file

Before

Width:  |  Height:  |  Size: 468 B

After

Width:  |  Height:  |  Size: 468 B

View file

Before

Width:  |  Height:  |  Size: 509 B

After

Width:  |  Height:  |  Size: 509 B

View file

Before

Width:  |  Height:  |  Size: 403 B

After

Width:  |  Height:  |  Size: 403 B

View file

Before

Width:  |  Height:  |  Size: 480 B

After

Width:  |  Height:  |  Size: 480 B

View file

Before

Width:  |  Height:  |  Size: 409 B

After

Width:  |  Height:  |  Size: 409 B

Some files were not shown because too many files have changed in this diff Show more