mirror of
https://github.com/2dust/v2rayN.git
synced 2026-11-11 23:15:01 +03:00
Add scanning QR code from image
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
using QRCoder;
|
||||
using SkiaSharp;
|
||||
using ZXing.SkiaSharp;
|
||||
|
||||
namespace ServiceLib.Common
|
||||
{
|
||||
@@ -11,5 +13,78 @@ namespace ServiceLib.Common
|
||||
using PngByteQRCode qrCode = new(qrCodeData);
|
||||
return qrCode.GetGraphic(20);
|
||||
}
|
||||
|
||||
public static string? ParseBarcode(string? fileName)
|
||||
{
|
||||
if (fileName == null || !File.Exists(fileName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var image = SKImage.FromEncodedData(fileName);
|
||||
var bitmap = SKBitmap.FromImage(image);
|
||||
|
||||
return ReaderBarcode(bitmap);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static string? ParseBarcode(byte[]? bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
var bitmap = SKBitmap.Decode(bytes);
|
||||
//using var stream = new FileStream("test2.png", FileMode.Create, FileAccess.Write);
|
||||
//using var image = SKImage.FromBitmap(bitmap);
|
||||
//using var encodedImage = image.Encode();
|
||||
//encodedImage.SaveTo(stream);
|
||||
return ReaderBarcode(bitmap);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static string? ReaderBarcode(SKBitmap? bitmap)
|
||||
{
|
||||
var reader = new BarcodeReader();
|
||||
var result = reader.Decode(bitmap);
|
||||
|
||||
if (result != null && Utils.IsNotEmpty(result.Text))
|
||||
{
|
||||
return result.Text;
|
||||
}
|
||||
|
||||
//FlipBitmap
|
||||
var result2 = reader.Decode(FlipBitmap(bitmap));
|
||||
return result2?.Text;
|
||||
}
|
||||
|
||||
private static SKBitmap FlipBitmap(SKBitmap bmp)
|
||||
{
|
||||
// Create a bitmap (to return)
|
||||
var flipped = new SKBitmap(bmp.Width, bmp.Height, bmp.Info.ColorType, bmp.Info.AlphaType);
|
||||
|
||||
// Create a canvas to draw into the bitmap
|
||||
using var canvas = new SKCanvas(flipped);
|
||||
|
||||
// Set a transform matrix which moves the bitmap to the right,
|
||||
// and then "scales" it by -1, which just flips the pixels
|
||||
// horizontally
|
||||
canvas.Translate(bmp.Width, 0);
|
||||
canvas.Scale(-1, 1);
|
||||
canvas.DrawBitmap(bmp, 0, 0);
|
||||
return flipped;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@
|
||||
ShareServer,
|
||||
ShowHideWindow,
|
||||
ScanScreenTask,
|
||||
ScanImageTask,
|
||||
Shutdown,
|
||||
BrowseServer,
|
||||
ImportRulesFromFile,
|
||||
|
||||
Generated
+9
@@ -681,6 +681,15 @@ namespace ServiceLib.Resx {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Scan QR code in the image 的本地化字符串。
|
||||
/// </summary>
|
||||
public static string menuAddServerViaImage {
|
||||
get {
|
||||
return ResourceManager.GetString("menuAddServerViaImage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 Scan QR code on the screen (Ctrl+S) 的本地化字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -1351,4 +1351,7 @@
|
||||
<data name="TbSettingsChinaUserTip" xml:space="preserve">
|
||||
<value>Users in China region can ignore this item</value>
|
||||
</data>
|
||||
<data name="menuAddServerViaImage" xml:space="preserve">
|
||||
<value>Scan QR code in the image</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1348,4 +1348,7 @@
|
||||
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
||||
<value>俄罗斯</value>
|
||||
</data>
|
||||
<data name="menuAddServerViaImage" xml:space="preserve">
|
||||
<value>扫描图片中的二维码</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -1228,4 +1228,7 @@
|
||||
<data name="menuRegionalPresetsRussia" xml:space="preserve">
|
||||
<value>俄羅斯</value>
|
||||
</data>
|
||||
<data name="menuAddServerViaImage" xml:space="preserve">
|
||||
<value>掃描圖片中的二維碼</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -16,7 +16,9 @@
|
||||
<PackageReference Include="WebDav.Client" Version="2.8.0" />
|
||||
<PackageReference Include="YamlDotNet" Version="16.1.3" />
|
||||
<PackageReference Include="QRCoder" Version="1.6.0" />
|
||||
<PackageReference Include="CliWrap" Version="3.6.6" />
|
||||
<PackageReference Include="CliWrap" Version="3.6.6" />
|
||||
<PackageReference Include="SkiaSharp.QrCode" Version="0.7.0" />
|
||||
<PackageReference Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -25,6 +25,7 @@ namespace ServiceLib.ViewModels
|
||||
public ReactiveCommand<Unit, Unit> AddCustomServerCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddServerViaClipboardCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; }
|
||||
public ReactiveCommand<Unit, Unit> AddServerViaImageCmd { get; }
|
||||
|
||||
//Subscription
|
||||
public ReactiveCommand<Unit, Unit> SubSettingCmd { get; }
|
||||
@@ -46,6 +47,7 @@ namespace ServiceLib.ViewModels
|
||||
|
||||
//Presets
|
||||
public ReactiveCommand<Unit, Unit> RegionalPresetDefaultCmd { get; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> RegionalPresetRussiaCmd { get; }
|
||||
|
||||
public ReactiveCommand<Unit, Unit> ReloadCmd { get; }
|
||||
@@ -121,7 +123,11 @@ namespace ServiceLib.ViewModels
|
||||
});
|
||||
AddServerViaScanCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await AddServerViaScanTaskAsync();
|
||||
await AddServerViaScanAsync();
|
||||
});
|
||||
AddServerViaImageCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||
{
|
||||
await AddServerViaImageAsync();
|
||||
});
|
||||
|
||||
//Subscription
|
||||
@@ -386,12 +392,34 @@ namespace ServiceLib.ViewModels
|
||||
}
|
||||
}
|
||||
|
||||
public async Task AddServerViaScanTaskAsync()
|
||||
public async Task AddServerViaScanAsync()
|
||||
{
|
||||
_updateView?.Invoke(EViewAction.ScanScreenTask, null);
|
||||
}
|
||||
|
||||
public void ScanScreenResult(string result)
|
||||
public async Task ScanScreenResult(byte[]? bytes)
|
||||
{
|
||||
var result = QRCodeHelper.ParseBarcode(bytes);
|
||||
await AddScanResultAsync(result);
|
||||
}
|
||||
|
||||
public async Task AddServerViaImageAsync()
|
||||
{
|
||||
_updateView?.Invoke(EViewAction.ScanImageTask, null);
|
||||
}
|
||||
|
||||
public async Task ScanImageResult(string fileName)
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(fileName))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var result = QRCodeHelper.ParseBarcode(fileName);
|
||||
await AddScanResultAsync(result);
|
||||
}
|
||||
|
||||
private async Task AddScanResultAsync(string? result)
|
||||
{
|
||||
if (Utils.IsNullOrEmpty(result))
|
||||
{
|
||||
@@ -571,6 +599,6 @@ namespace ServiceLib.ViewModels
|
||||
Reload();
|
||||
}
|
||||
|
||||
#endregion
|
||||
#endregion Presets
|
||||
}
|
||||
}
|
||||
@@ -211,7 +211,7 @@ namespace ServiceLib.ViewModels
|
||||
private async Task AddServerViaScan()
|
||||
{
|
||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||
if (service != null) await service.AddServerViaScanTaskAsync();
|
||||
if (service != null) await service.AddServerViaScanAsync();
|
||||
}
|
||||
|
||||
private async Task UpdateSubscriptionProcess(bool blProxy)
|
||||
|
||||
Reference in New Issue
Block a user