├── .gitignore
├── README.md
├── WarFactory.Android
├── MainActivity.cs
├── MyAndroidInterface.cs
├── Properties
│ ├── AndroidManifest.xml
│ └── AssemblyInfo.cs
├── Resources
│ ├── AboutResources.txt
│ ├── Resource.designer.cs
│ ├── mipmap-anydpi-v26
│ │ ├── icon.xml
│ │ └── icon_round.xml
│ ├── mipmap-hdpi
│ │ ├── icon.png
│ │ └── launcher_foreground.png
│ ├── mipmap-mdpi
│ │ ├── icon.png
│ │ └── launcher_foreground.png
│ ├── mipmap-xhdpi
│ │ ├── icon.png
│ │ └── launcher_foreground.png
│ ├── mipmap-xxhdpi
│ │ ├── icon.png
│ │ └── launcher_foreground.png
│ ├── mipmap-xxxhdpi
│ │ ├── icon.png
│ │ └── launcher_foreground.png
│ └── values
│ │ ├── colors.xml
│ │ └── styles.xml
├── WarFactory.Android.csproj
└── WarFactory.Android.csproj.user
├── WarFactory.iOS
├── AppDelegate.cs
├── Entitlements.plist
├── Info.plist
├── Main.cs
├── MyiOSInterface.cs
├── Properties
│ └── AssemblyInfo.cs
├── Resources
│ ├── Default-568h@2x.png
│ ├── Default-Portrait.png
│ ├── Default-Portrait@2x.png
│ ├── Default.png
│ ├── Default@2x.png
│ └── LaunchScreen.storyboard
├── WarFactory.iOS.csproj
└── WarFactory.iOS.csproj.user
├── WarFactory.sln
├── WarFactory
├── App.xaml
├── App.xaml.cs
├── AssemblyInfo.cs
├── FactoryFunc
│ ├── LsbTank.cs
│ └── MirageTank.cs
├── MainPage.xaml
├── MainPage.xaml.cs
├── MyInterface
│ └── IPlatformInterface.cs
├── Resources
│ ├── BaiduNetDisk.png
│ ├── File.png
│ ├── GitHub.png
│ ├── Images.png
│ ├── LanZouYun.png
│ ├── LsbTank.png
│ ├── MirageTank.png
│ ├── Tieba.png
│ ├── Version.txt
│ ├── WeiYun.png
│ └── simhei.ttf
├── ViewPage
│ ├── AboutPage.xaml
│ ├── AboutPage.xaml.cs
│ ├── CourseForLsbTank.xaml
│ ├── CourseForLsbTank.xaml.cs
│ ├── CourseForMirageTank.xaml
│ ├── CourseForMirageTank.xaml.cs
│ ├── ImageListPage.xaml
│ ├── ImageListPage.xaml.cs
│ ├── ImagePage.xaml
│ ├── ImagePage.xaml.cs
│ ├── LsbTankAdvancedFunctionPage.xaml
│ ├── LsbTankAdvancedFunctionPage.xaml.cs
│ ├── LsbTankPage.xaml
│ ├── LsbTankPage.xaml.cs
│ ├── LsbTankSettingPage.xaml
│ ├── LsbTankSettingPage.xaml.cs
│ ├── MirageTankPage.xaml
│ ├── MirageTankPage.xaml.cs
│ ├── MirageTankSettingPage.xaml
│ ├── MirageTankSettingPage.xaml.cs
│ ├── VersionPage.xaml
│ └── VersionPage.xaml.cs
└── WarFactory.csproj
└── Xamarin ico Creator
├── AppIcon.appiconset
├── Icon1024.png
├── Icon120.png
├── Icon152.png
├── Icon167.png
├── Icon180.png
├── Icon20.png
├── Icon29.png
├── Icon40.png
├── Icon58.png
├── Icon60.png
├── Icon76.png
├── Icon80.png
└── Icon87.png
├── Resources
├── mipmap-hdpi
│ ├── icon.png
│ └── launcher_foreground.png
├── mipmap-mdpi
│ ├── icon.png
│ └── launcher_foreground.png
├── mipmap-xhdpi
│ ├── icon.png
│ └── launcher_foreground.png
├── mipmap-xxhdpi
│ ├── icon.png
│ └── launcher_foreground.png
└── mipmap-xxxhdpi
│ ├── icon.png
│ └── launcher_foreground.png
├── SkiaSharp.dll
├── WarFactory.png
├── Xamarin ico Creator.deps.json
├── Xamarin ico Creator.dll
├── Xamarin ico Creator.exe
├── Xamarin ico Creator.pdb
├── Xamarin ico Creator.runtimeconfig.dev.json
├── Xamarin ico Creator.runtimeconfig.json
├── ref
└── Xamarin ico Creator.dll
└── runtimes
├── osx
└── native
│ └── libSkiaSharp.dylib
├── win-arm64
└── native
│ └── libSkiaSharp.dll
├── win-x64
└── native
│ └── libSkiaSharp.dll
└── win-x86
└── native
└── libSkiaSharp.dll
/.gitignore:
--------------------------------------------------------------------------------
1 | /.vs
2 | /WarFactory/bin
3 | /WarFactory/obj
4 | /WarFactory.Android/Assets
5 | /WarFactory.Android/bin
6 | /WarFactory.Android/obj
7 | /WarFactory.iOS/Assets.xcassets
8 | /WarFactory.iOS/bin
9 | /WarFactory.iOS/obj
10 |
11 | /WarFactory/Resources/Pay.png
12 | /WarFactory/ViewPage/AboutPage.xaml
13 | /WarFactory/ViewPage/AboutPage.xaml.cs
14 | /WarFactory/ViewPage/PayPage.xaml
15 | /WarFactory/ViewPage/PayPage.xaml.cs
16 |
17 | /发布版APK文件
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WarFactory——战车工厂
2 |
3 | **无影开发无期暂停,引流带来了太多恶性事件,望周知!**
4 |
5 | **幻影坦克+无影坦克全面手机APP解决方案(手动滑稽)**
6 |
7 | 在这个APP中,你可以用你的手机生成一张幻影坦克图片(目前只支持灰度),也可以生成或现形一张无影坦克图片
8 |
9 | 发布版APK文件附在GitHub项目根目录,方便在网盘挂掉后获取下载更新。
10 | 你也可以在腾讯微云下载已经打包好的APK文件:https://share.weiyun.com/yvkPZ89G 密码:warfac
11 | ~~你也可以在百度网盘下载已经打包好的APK文件: https://pan.baidu.com/s/1B9Aw7J_cKA6W5GwNodRzPA 提取码:pbd6~~
12 | 百度贴吧帖子: https://tieba.baidu.com/p/7308060718 https://tieba.baidu.com/p/7308042884
13 |
14 | **使用方法详见APP内部**
15 |
16 | 这是一个Xamarin.Form解决方案,但目前仅编写了Android项目。
17 | 主要的幻影/无影坦克的核心编解码类位于WarFactory项目下FactoryFunc目录中
18 | 项目根目录附上了一个我自己写的用于生成Xamarin.Android中应用程序图标的C# Console程序。
19 |
20 | By: f_Endman
21 |
22 | **更新日志:**
23 | Version 1.0
24 | 2021-04-18
25 | 软件发布,基本实现幻影坦克和无影坦克的编解码,尚存在一些Bug
26 |
27 | Version 1.1
28 | 2021-04-24
29 | 做了许多调整,包括但不仅限于
30 | 1.调整UI
31 | 幻影坦克工厂将亮度系数以及阈值的调整移入了一个新界面
32 | 查看大图界面添加了滚动功能,可以浏览较长的图片
33 | 2.无影坦克现形现在可以选择多张图片进行解码了(直接全选相册,High到不行),非图片文件增加了图标显示,大部分图片无需保存即可直接查看,其他文件可保存后即可点击打开
34 | 3.优化了算法,现在能够解码压缩度为5的坦克图了(之前不知道还有这个)
35 | 4.修复了若干Bug,包括但不仅限于:
36 | 第一次打开应用直接解无影坦克而导致闪退的问题
37 | 生成幻影坦克时的闪退问题
38 | 有损坏的图进行解码会导致闪退的问题
39 | …………
40 |
41 | Version 1.2
42 | 2021-05-16
43 | 修复了图片保存后相册中找不到的Bug
44 |
45 | Version 1.3
46 | 2021-06-19
47 | 添加了对左上角的水印的自定义功能
48 | 暂时解决了证书问题
49 | 增加了微信赞赏界面,因此出于隐私问题隐藏了该GitHub储存库的大部分文件,只保留了关键算法和UI部分,从今往后该解决方案将不再能直接打开,需要专业人士自行移植到自己的解决方案里,还望体谅
50 |
51 | Version 1.3.1
52 | 2021-06-19
53 | 修改了幻影图的生成:
54 | 现在表图里图高宽比不一样的时候会保持原高宽比居中拉伸
55 | 减轻了幻影图色差过大时出现黑色条纹的现象
56 |
57 | Version 1.3.2
58 | 2021-06-21
59 | 修复了无影现形时可能引起闪退的中文文件名乱码问题
60 | 添加了主界面右下角软件版本的显示
61 |
62 | Version 1.4
63 | 2021-06-21
64 | 添加了无影生成时表图里图的多选批量生成
65 |
66 | Version 1.5
67 | 2021-06-23
68 | 改良了生成无影坦克的算法,现在1-7压缩度的图都能生成(6和7属于测试,兼容性稳定性都很差)
69 | 改进了UI
70 |
71 | Version 1.5.1
72 | 2021-06-25
73 | 大调了安卓的图片保存接口,应该能解决之前的保存崩溃问题
74 | 调整了UI
75 |
76 | Version 1.6
77 | 2021-06-26
78 | 目前为止最大的功能性更新
79 | 无影现形加入高级功能:
80 | 1.捕获模式:开启后可以切到后台下载图片,过程中新增的图片都会被添加进要现形的队列!
81 | 2.一键添加新图:点击后会一键添加自上次打开应用以来新增的图片到要现形的队列!
82 | 调整了UI
83 |
84 |
85 |
86 | **附录**
87 | 2021-06-25
88 | iOS已经在模拟器上开发好了
89 | 但我没有Apple开发者账号,这玩意是要花钱的,如此一来我就没法分发,也就发不上来了
90 | 再加上我的iOS开发环境极度恶劣(本人无任何苹果设备只能在Windows上运行的Mac模拟器上再运行iOS模拟器,帧数高达2帧!)
91 | 再加上iOS那个极其离谱的Photos框架,我的耐心已经被消磨殆尽了Orz。。估计以后也不会再有iOS开发计划了QAQ。。
92 |
--------------------------------------------------------------------------------
/WarFactory.Android/MainActivity.cs:
--------------------------------------------------------------------------------
1 | using Android.App;
2 | using Android.Content.PM;
3 | using Android.Runtime;
4 | using Android.OS;
5 |
6 | namespace WarFactory.Droid
7 | {
8 | [Activity(Label = "战车工厂", Icon = "@mipmap/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize, ScreenOrientation = ScreenOrientation.Portrait)]
9 | public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
10 | {
11 | protected override void OnCreate(Bundle savedInstanceState)
12 | {
13 | base.OnCreate(savedInstanceState);
14 |
15 | Xamarin.Essentials.Platform.Init(this, savedInstanceState);
16 | global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
17 | LoadApplication(new App());
18 | }
19 | public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
20 | {
21 | Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
22 |
23 | base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/WarFactory.Android/MyAndroidInterface.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Threading.Tasks;
4 | using Xamarin.Forms;
5 | using Xamarin.Essentials;
6 | using WarFactory.MyInterface;
7 | using Android.Media;
8 | using Android.Provider;
9 | using Android.Graphics;
10 | using Android.Database;
11 | using Environment = Android.OS.Environment;
12 | using Path = System.IO.Path;
13 | using System.Collections.Generic;
14 |
15 | [assembly: Dependency(typeof(WarFactory.Droid.PlatformService))]
16 | namespace WarFactory.Droid
17 | {
18 | public class PlatformService : IPlatformService
19 | {
20 | private readonly string albumName = "战车工厂";
21 |
22 | public async Task ImageSave(MemoryStream stream, bool compatibleMode, string fileName = null)
23 | {
24 | await Permissions.RequestAsync();
25 | if (Permissions.ShouldShowRationale()) return "...保存个屁!不给爷权限还想让爷造坦克?";
26 | await Permissions.RequestAsync();
27 | if (Permissions.ShouldShowRationale()) return "...保存个屁!不给爷权限还想让爷造坦克?";
28 |
29 | //用于替代Environment.ExternalStorageDirectory
30 | //GetExternalFilesDir()会获取到 /storage/emulated/0/Android/data/应用包名/files
31 | string externalRootPath;
32 | if (compatibleMode)
33 | {
34 | externalRootPath = "/storage/emulated/0/";
35 | }
36 | else
37 | {
38 | DirectoryInfo externalStorageDir = new DirectoryInfo(Platform.AppContext.GetExternalFilesDir(null).AbsolutePath);
39 | externalRootPath = externalStorageDir.Parent.Parent.Parent.Parent.FullName;
40 | }
41 | string path = Path.Combine(externalRootPath, Environment.DirectoryPictures, albumName);
42 | if (fileName == null || fileName == "") fileName = "Tank_" + DateTime.Now.ToLocalTime().ToString("yyyyMMdd_HHmmss") + ".png";
43 |
44 | try
45 | {
46 | if (Directory.Exists(path) == false)
47 | Directory.CreateDirectory(path);
48 | }
49 | catch(UnauthorizedAccessException)
50 | {
51 | return "。。。保存失败!创建目录失败!!动态获取的目录为:" + path + "请尝试兼容模式!!";
52 | }
53 |
54 | path = Path.Combine(path, fileName);
55 | FileStream photoTankFile = new FileStream(path, FileMode.Create);
56 | byte[] photoTank = stream.ToArray();
57 | photoTankFile.Write(photoTank, 0, photoTank.Length);
58 | photoTankFile.Flush();
59 | photoTankFile.Close();
60 |
61 | string[] paths = { path };
62 | MediaScannerConnection.ScanFile(Platform.AppContext, paths, null, null);
63 |
64 | return Path.Combine(fileName);
65 | }
66 |
67 | public async Task RequestPermissions()
68 | {
69 | await Permissions.RequestAsync();
70 | if (Permissions.ShouldShowRationale()) return;
71 | await Permissions.RequestAsync();
72 | if (Permissions.ShouldShowRationale()) return;
73 | }
74 |
75 | public string GetAbsoluteSavePath()
76 | {
77 | //用于替代Environment.ExternalStorageDirectory
78 | //GetExternalFilesDir()会获取到 /storage/emulated/0/Android/data/应用包名/files
79 | DirectoryInfo externalStorageDir = new DirectoryInfo(Platform.AppContext.GetExternalFilesDir(null).AbsolutePath);
80 | return Path.Combine(externalStorageDir.Parent.Parent.Parent.Parent.FullName, Environment.DirectoryPictures, albumName);
81 | }
82 |
83 | public string GetSavePath()
84 | {
85 | return Path.Combine(Environment.DirectoryPictures, albumName);
86 | }
87 |
88 | public string GetVersion()
89 | {
90 | return AppInfo.VersionString;
91 | }
92 |
93 | //返回所有保存时间比这个时间点晚的图片的路径
94 | [Obsolete] //烦死了!
95 | public string[] GetLatestPictures(long timestamp)
96 | {
97 | //相当于是得到了一个纵列是Data和DateTaken,横排是按DateTaken从新到旧排列的列表(cursor)
98 | ICursor cursor = Platform.AppContext.ContentResolver.Query(
99 | MediaStore.Images.Media.ExternalContentUri,
100 | new string[] { MediaStore.Images.Media.InterfaceConsts.Data, MediaStore.Images.Media.InterfaceConsts.DateTaken },
101 | null,
102 | null,
103 | MediaStore.Images.Media.InterfaceConsts.DateTaken + " desc");
104 | List paths = new List();
105 | while (cursor.MoveToNext())
106 | {
107 | long picTimestamp = cursor.GetLong(cursor.GetColumnIndexOrThrow(MediaStore.Images.Media.InterfaceConsts.DateTaken));
108 | if (timestamp < picTimestamp)
109 | {
110 | string fileName = cursor.GetString(cursor.GetColumnIndex(MediaStore.Images.Media.InterfaceConsts.Data));
111 | paths.Add(fileName);
112 | }
113 | else //由于DateTaken是从新到旧的,所以现在这个不是新增的,之后的也都不会是
114 | break;
115 | }
116 | cursor.Dispose();
117 | return paths.ToArray();
118 | }
119 | }
120 | }
--------------------------------------------------------------------------------
/WarFactory.Android/Properties/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/WarFactory.Android/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 | using Android.App;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("WarFactory")]
10 | [assembly: AssemblyDescription("")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("")]
13 | [assembly: AssemblyProduct("WarFactory")]
14 | [assembly: AssemblyCopyright("Copyright © 2014")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 | [assembly: ComVisible(false)]
18 |
19 | // Version information for an assembly consists of the following four values:
20 | //
21 | // Major Version
22 | // Minor Version
23 | // Build Number
24 | // Revision
25 | [assembly: AssemblyVersion("1.0.0.0")]
26 | [assembly: AssemblyFileVersion("1.0.0.0")]
27 |
28 | // Add some common permissions, these can be removed if not needed
29 | [assembly: UsesPermission(Android.Manifest.Permission.Internet)]
30 | [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
31 |
32 | // Needed for Picking photo/video
33 | [assembly: UsesPermission(Android.Manifest.Permission.ReadExternalStorage)]
34 | // Needed for Taking photo/video
35 | [assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/AboutResources.txt:
--------------------------------------------------------------------------------
1 | Images, layout descriptions, binary blobs and string dictionaries can be included
2 | in your application as resource files. Various Android APIs are designed to
3 | operate on the resource IDs instead of dealing with images, strings or binary blobs
4 | directly.
5 |
6 | For example, a sample Android app that contains a user interface layout (main.xml),
7 | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
8 | would keep its resources in the "Resources" directory of the application:
9 |
10 | Resources/
11 | drawable-hdpi/
12 | icon.png
13 |
14 | drawable-ldpi/
15 | icon.png
16 |
17 | drawable-mdpi/
18 | icon.png
19 |
20 | layout/
21 | main.xml
22 |
23 | values/
24 | strings.xml
25 |
26 | In order to get the build system to recognize Android resources, set the build action to
27 | "AndroidResource". The native Android APIs do not operate directly with filenames, but
28 | instead operate on resource IDs. When you compile an Android application that uses resources,
29 | the build system will package the resources for distribution and generate a class called
30 | "Resource" that contains the tokens for each one of the resources included. For example,
31 | for the above Resources layout, this is what the Resource class would expose:
32 |
33 | public class Resource {
34 | public class drawable {
35 | public const int icon = 0x123;
36 | }
37 |
38 | public class layout {
39 | public const int main = 0x456;
40 | }
41 |
42 | public class strings {
43 | public const int first_string = 0xabc;
44 | public const int second_string = 0xbcd;
45 | }
46 | }
47 |
48 | You would then use R.drawable.icon to reference the drawable/icon.png file, or Resource.layout.main
49 | to reference the layout/main.xml file, or Resource.strings.first_string to reference the first
50 | string in the dictionary file values/strings.xml.
51 |
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/mipmap-anydpi-v26/icon.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/mipmap-anydpi-v26/icon_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/mipmap-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.Android/Resources/mipmap-hdpi/icon.png
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/mipmap-hdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.Android/Resources/mipmap-hdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/mipmap-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.Android/Resources/mipmap-mdpi/icon.png
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/mipmap-mdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.Android/Resources/mipmap-mdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/mipmap-xhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.Android/Resources/mipmap-xhdpi/icon.png
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/mipmap-xhdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.Android/Resources/mipmap-xhdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/mipmap-xxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.Android/Resources/mipmap-xxhdpi/icon.png
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/mipmap-xxhdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.Android/Resources/mipmap-xxhdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/mipmap-xxxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.Android/Resources/mipmap-xxxhdpi/icon.png
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.Android/Resources/mipmap-xxxhdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #FFFFFF
4 | #3F51B5
5 | #303F9F
6 | #FF4081
7 |
8 |
--------------------------------------------------------------------------------
/WarFactory.Android/Resources/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
--------------------------------------------------------------------------------
/WarFactory.Android/WarFactory.Android.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}
7 | {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
8 | {c9e5eea5-ca05-42a1-839b-61506e0a37df}
9 | Library
10 | WarFactory.Droid
11 | WarFactory.Android
12 | True
13 | True
14 | Resources\Resource.designer.cs
15 | Resource
16 | Properties\AndroidManifest.xml
17 | Resources
18 | Assets
19 | false
20 | v11.0
21 | true
22 | true
23 | Xamarin.Android.Net.AndroidClientHandler
24 |
25 |
26 |
27 |
28 | true
29 | portable
30 | false
31 | bin\Debug
32 | DEBUG;
33 | prompt
34 | 4
35 | None
36 |
37 |
38 | true
39 | portable
40 | true
41 | bin\Release
42 | prompt
43 | 4
44 | true
45 | false
46 | false
47 | false
48 | false
49 | false
50 | true
51 | C:\Users\17494\AppData\Local\Xamarin\Mono for Android\Keystore\fjj\fjj.keystore
52 | 051204
53 | fjj
54 | 051204
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | {7D5A572C-7F25-490D-9F75-88DB28B94DD4}
99 | WarFactory
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/WarFactory.Android/WarFactory.Android.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | pixel_2_pie_9_0_-_api_28
5 | pixel_2_pie_9_0_-_api_28
6 | pixel_2_pie_9_0_-_api_28
7 | MainTheme
8 |
9 |
--------------------------------------------------------------------------------
/WarFactory.iOS/AppDelegate.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace WarFactory.iOS
9 | {
10 | // The UIApplicationDelegate for the application. This class is responsible for launching the
11 | // User Interface of the application, as well as listening (and optionally responding) to
12 | // application events from iOS.
13 | [Register("AppDelegate")]
14 | public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
15 | {
16 | //
17 | // This method is invoked when the application has loaded and is ready to run. In this
18 | // method you should instantiate the window, load the UI into it and then make the window
19 | // visible.
20 | //
21 | // You have 17 seconds to return from this method, or iOS will terminate your application.
22 | //
23 | public override bool FinishedLaunching(UIApplication app, NSDictionary options)
24 | {
25 | global::Xamarin.Forms.Forms.Init();
26 | LoadApplication(new App());
27 |
28 | return base.FinishedLaunching(app, options);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/WarFactory.iOS/Entitlements.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/WarFactory.iOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIDeviceFamily
6 |
7 | 1
8 | 2
9 |
10 | UISupportedInterfaceOrientations
11 |
12 | UIInterfaceOrientationPortrait
13 |
14 | UISupportedInterfaceOrientations~ipad
15 |
16 | UIInterfaceOrientationPortrait
17 | UIInterfaceOrientationPortraitUpsideDown
18 | UIInterfaceOrientationLandscapeLeft
19 | UIInterfaceOrientationLandscapeRight
20 |
21 | MinimumOSVersion
22 | 8.0
23 | CFBundleDisplayName
24 | 战车工厂
25 | CFBundleIdentifier
26 | com.WarFactory
27 | CFBundleVersion
28 | 1.6
29 | CFBundleName
30 | WarFactory
31 | XSAppIconAssets
32 | Assets.xcassets/AppIcon.appiconset
33 | CFBundleShortVersionString
34 | 1.6
35 | UILaunchStoryboardName
36 | LaunchScreen
37 | LSSupportsOpeningDocumentsInPlace
38 |
39 | UIFileSharingEnabled
40 |
41 | NSPhotoLibraryAddUsageDescription
42 | New Entry
43 | NSPhotoLibraryUsageDescription
44 | New Entry
45 |
46 |
47 |
--------------------------------------------------------------------------------
/WarFactory.iOS/Main.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 |
5 | using Foundation;
6 | using UIKit;
7 |
8 | namespace WarFactory.iOS
9 | {
10 | public class Application
11 | {
12 | // This is the main entry point of the application.
13 | static void Main(string[] args)
14 | {
15 | // if you want to use a different Application Delegate class from "AppDelegate"
16 | // you can specify it here.
17 | UIApplication.Main(args, null, "AppDelegate");
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/WarFactory.iOS/MyiOSInterface.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Threading.Tasks;
4 | using WarFactory.MyInterface;
5 | using Xamarin.Essentials;
6 | using Xamarin.Forms;
7 | using Photos;
8 | using Foundation;
9 | using MimeMapping;
10 |
11 | [assembly: Dependency(typeof(WarFactory.iOS.PlatformService))]
12 | namespace WarFactory.iOS
13 | {
14 | class PlatformService : IPlatformService
15 | {
16 | private readonly string albumName = "战车工厂";
17 |
18 | public async Task ImageSave(MemoryStream stream, bool compatibleMode, string fileName = null)
19 | {
20 | NSError error = null;
21 |
22 | //虽然对于iOS没有这两个权限,但要保证方法异步,所以还是保留下来了
23 | await Permissions.RequestAsync();
24 | await Permissions.RequestAsync();
25 |
26 | //判断相册是否存在,不存在就创建
27 | PHAssetCollection appAlbum = null;
28 | PHFetchResult albums = PHAssetCollection.FetchAssetCollections(PHAssetCollectionType.Album, PHAssetCollectionSubtype.Any, null);
29 | foreach (PHAssetCollection album in albums)
30 | {
31 | if (album.LocalizedTitle == albumName)
32 | appAlbum = album;
33 | }
34 | if (appAlbum == null) //相册不存在,新建
35 | {
36 | string[] albumID = new string[1];
37 | PHPhotoLibrary.SharedPhotoLibrary.PerformChangesAndWait(() =>
38 | {
39 | albumID[0] = PHAssetCollectionChangeRequest.CreateAssetCollection(albumName).PlaceholderForCreatedAssetCollection.LocalIdentifier;
40 | }, out error);
41 | appAlbum = PHAssetCollection.FetchAssetCollections(albumID, null)[0] as PHAssetCollection;
42 | }
43 |
44 | //获取路径及名称
45 | string documentsPath;
46 | documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
47 | if (fileName == null || fileName == "") fileName = "Tank_" + DateTime.Now.ToLocalTime().ToString("yyyyMMdd_HHmmss") + ".png";
48 | string path = Path.Combine(documentsPath, fileName);
49 |
50 | //保存
51 | FileStream photoTankFile = new FileStream(path, FileMode.Create);
52 | byte[] photoTank = stream.ToArray();
53 | photoTankFile.Write(photoTank, 0, photoTank.Length);
54 | photoTankFile.Flush();
55 | photoTankFile.Close();
56 |
57 | //如果是图片或视频,就添加到相册里
58 | string MimeType = MimeUtility.GetMimeMapping(path);
59 | if (MimeType.IndexOf("image") != -1 || MimeType.IndexOf("video") != -1)
60 | {
61 | string[] assetID = new string[1];
62 | PHPhotoLibrary.SharedPhotoLibrary.PerformChangesAndWait(() =>
63 | {
64 | if (MimeType.IndexOf("image") != -1)
65 | assetID[0] = PHAssetChangeRequest.FromImage(new NSUrl(path, true)).PlaceholderForCreatedAsset.LocalIdentifier;
66 | if (MimeType.IndexOf("video") != -1)
67 | assetID[0] = PHAssetChangeRequest.FromVideo(new NSUrl(path, true)).PlaceholderForCreatedAsset.LocalIdentifier;
68 | }, out error);
69 | PHAsset asset = PHAsset.FetchAssetsUsingLocalIdentifiers(assetID, null)[0] as PHAsset;
70 | PHObject[] objs = { asset };
71 | PHPhotoLibrary.SharedPhotoLibrary.PerformChangesAndWait(() =>
72 | {
73 | PHAssetCollectionChangeRequest collectionChangeRequest = PHAssetCollectionChangeRequest.ChangeRequest(appAlbum);
74 | collectionChangeRequest.InsertAssets(objs, new NSIndexSet(0));
75 | }, out error);
76 | }
77 |
78 | return Path.Combine(fileName);
79 | }
80 |
81 | public async Task RequestPermissions()
82 | {
83 | await Permissions.RequestAsync();
84 | await Permissions.RequestAsync();
85 | }
86 |
87 | public string GetAbsoluteSavePath()
88 | {
89 | return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
90 | }
91 |
92 | public string GetSavePath()
93 | {
94 | return "(不会真的有人想看iOS的全部路径吧(¬_¬) )";//GetAbsoluteSavePath();
95 | }
96 |
97 | public string GetVersion()
98 | {
99 | return AppInfo.VersionString;
100 | }
101 |
102 | public string[] GetLatestPictures(long timestamp)
103 | {
104 | return null;
105 | }
106 | }
107 | }
--------------------------------------------------------------------------------
/WarFactory.iOS/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("WarFactory.iOS")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("WarFactory.iOS")]
13 | [assembly: AssemblyCopyright("Copyright © 2014")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("72bdc44f-c588-44f3-b6df-9aace7daafdd")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/WarFactory.iOS/Resources/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.iOS/Resources/Default-568h@2x.png
--------------------------------------------------------------------------------
/WarFactory.iOS/Resources/Default-Portrait.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.iOS/Resources/Default-Portrait.png
--------------------------------------------------------------------------------
/WarFactory.iOS/Resources/Default-Portrait@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.iOS/Resources/Default-Portrait@2x.png
--------------------------------------------------------------------------------
/WarFactory.iOS/Resources/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.iOS/Resources/Default.png
--------------------------------------------------------------------------------
/WarFactory.iOS/Resources/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory.iOS/Resources/Default@2x.png
--------------------------------------------------------------------------------
/WarFactory.iOS/Resources/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/WarFactory.iOS/WarFactory.iOS.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | iPhoneSimulator
6 | 8.0.30703
7 | 2.0
8 | {BD93B29D-C293-4564-AA60-856949752594}
9 | {FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
10 | {6143fdea-f3c2-4a09-aafa-6e230626515e}
11 | Exe
12 | WarFactory.iOS
13 | Resources
14 | WarFactory.iOS
15 | true
16 | NSUrlSessionHandler
17 | automatic
18 | true
19 |
20 |
21 | true
22 | full
23 | false
24 | bin\iPhoneSimulator\Debug
25 | DEBUG
26 | prompt
27 | 4
28 | x86_64
29 | None
30 | true
31 |
32 |
33 | none
34 | true
35 | bin\iPhoneSimulator\Release
36 | prompt
37 | 4
38 | None
39 | x86_64
40 |
41 |
42 | true
43 | full
44 | false
45 | bin\iPhone\Debug
46 | DEBUG
47 | prompt
48 | 4
49 | ARM64
50 | iPhone Developer
51 | true
52 | Entitlements.plist
53 | None
54 | -all
55 |
56 |
57 | none
58 | true
59 | bin\iPhone\Release
60 | prompt
61 | 4
62 | ARM64
63 | iPhone Developer
64 | Entitlements.plist
65 | true
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | false
84 |
85 |
86 | false
87 |
88 |
89 | false
90 |
91 |
92 | false
93 |
94 |
95 | false
96 |
97 |
98 | false
99 |
100 |
101 | false
102 |
103 |
104 | false
105 |
106 |
107 | false
108 |
109 |
110 | false
111 |
112 |
113 | false
114 |
115 |
116 | false
117 |
118 |
119 | false
120 |
121 |
122 | false
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 | {7D5A572C-7F25-490D-9F75-88DB28B94DD4}
141 | WarFactory
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
--------------------------------------------------------------------------------
/WarFactory.iOS/WarFactory.iOS.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | iPhone 12 iOS 14.5
5 | iPhone 12 iOS 14.5
6 | iPhone 12 iOS 14.5
7 |
8 |
--------------------------------------------------------------------------------
/WarFactory.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.31129.286
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WarFactory.Android", "WarFactory.Android\WarFactory.Android.csproj", "{5ECD5887-C030-4EFA-B0C3-D7EB63792FED}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WarFactory.iOS", "WarFactory.iOS\WarFactory.iOS.csproj", "{BD93B29D-C293-4564-AA60-856949752594}"
9 | EndProject
10 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WarFactory", "WarFactory\WarFactory.csproj", "{7F221777-66B6-48F0-96BF-49DD09FB5BD5}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Debug|iPhone = Debug|iPhone
16 | Debug|iPhoneSimulator = Debug|iPhoneSimulator
17 | Release|Any CPU = Release|Any CPU
18 | Release|iPhone = Release|iPhone
19 | Release|iPhoneSimulator = Release|iPhoneSimulator
20 | EndGlobalSection
21 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
25 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Debug|iPhone.ActiveCfg = Debug|Any CPU
26 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Debug|iPhone.Build.0 = Debug|Any CPU
27 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Debug|iPhone.Deploy.0 = Debug|Any CPU
28 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
29 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
30 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
31 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Release|Any CPU.ActiveCfg = Release|Any CPU
32 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Release|Any CPU.Build.0 = Release|Any CPU
33 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Release|Any CPU.Deploy.0 = Release|Any CPU
34 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Release|iPhone.ActiveCfg = Release|Any CPU
35 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Release|iPhone.Build.0 = Release|Any CPU
36 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Release|iPhone.Deploy.0 = Release|Any CPU
37 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
38 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
39 | {5ECD5887-C030-4EFA-B0C3-D7EB63792FED}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
40 | {BD93B29D-C293-4564-AA60-856949752594}.Debug|Any CPU.ActiveCfg = Debug|iPhone
41 | {BD93B29D-C293-4564-AA60-856949752594}.Debug|Any CPU.Build.0 = Debug|iPhone
42 | {BD93B29D-C293-4564-AA60-856949752594}.Debug|Any CPU.Deploy.0 = Debug|iPhone
43 | {BD93B29D-C293-4564-AA60-856949752594}.Debug|iPhone.ActiveCfg = Debug|iPhone
44 | {BD93B29D-C293-4564-AA60-856949752594}.Debug|iPhone.Build.0 = Debug|iPhone
45 | {BD93B29D-C293-4564-AA60-856949752594}.Debug|iPhone.Deploy.0 = Debug|iPhone
46 | {BD93B29D-C293-4564-AA60-856949752594}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
47 | {BD93B29D-C293-4564-AA60-856949752594}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
48 | {BD93B29D-C293-4564-AA60-856949752594}.Debug|iPhoneSimulator.Deploy.0 = Debug|iPhoneSimulator
49 | {BD93B29D-C293-4564-AA60-856949752594}.Release|Any CPU.ActiveCfg = Release|iPhoneSimulator
50 | {BD93B29D-C293-4564-AA60-856949752594}.Release|Any CPU.Build.0 = Release|iPhoneSimulator
51 | {BD93B29D-C293-4564-AA60-856949752594}.Release|Any CPU.Deploy.0 = Release|iPhoneSimulator
52 | {BD93B29D-C293-4564-AA60-856949752594}.Release|iPhone.ActiveCfg = Release|iPhone
53 | {BD93B29D-C293-4564-AA60-856949752594}.Release|iPhone.Build.0 = Release|iPhone
54 | {BD93B29D-C293-4564-AA60-856949752594}.Release|iPhone.Deploy.0 = Release|iPhone
55 | {BD93B29D-C293-4564-AA60-856949752594}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
56 | {BD93B29D-C293-4564-AA60-856949752594}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
57 | {BD93B29D-C293-4564-AA60-856949752594}.Release|iPhoneSimulator.Deploy.0 = Release|iPhoneSimulator
58 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
59 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
60 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
61 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Debug|iPhone.ActiveCfg = Debug|Any CPU
62 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Debug|iPhone.Build.0 = Debug|Any CPU
63 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Debug|iPhone.Deploy.0 = Debug|Any CPU
64 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
65 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
66 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Debug|iPhoneSimulator.Deploy.0 = Debug|Any CPU
67 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
68 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Release|Any CPU.Build.0 = Release|Any CPU
69 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Release|Any CPU.Deploy.0 = Release|Any CPU
70 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Release|iPhone.ActiveCfg = Release|Any CPU
71 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Release|iPhone.Build.0 = Release|Any CPU
72 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Release|iPhone.Deploy.0 = Release|Any CPU
73 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
74 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
75 | {7F221777-66B6-48F0-96BF-49DD09FB5BD5}.Release|iPhoneSimulator.Deploy.0 = Release|Any CPU
76 | EndGlobalSection
77 | GlobalSection(SolutionProperties) = preSolution
78 | HideSolutionNode = FALSE
79 | EndGlobalSection
80 | GlobalSection(ExtensibilityGlobals) = postSolution
81 | SolutionGuid = {35C4A60D-7BB1-487D-9D45-70FDE7ADC05E}
82 | EndGlobalSection
83 | EndGlobal
84 |
--------------------------------------------------------------------------------
/WarFactory/App.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/WarFactory/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xamarin.Forms;
3 | using WarFactory.MyInterface;
4 | using WarFactory.ViewPage;
5 | using System.IO;
6 | using Xamarin.Essentials;
7 |
8 | namespace WarFactory
9 | {
10 | public partial class App : Application
11 | {
12 | public App()
13 | {
14 | InitializeComponent();
15 |
16 | //获取上次打开应用的时间戳
17 | string fileName = Path.Combine(FileSystem.AppDataDirectory, "LastOpenedTimeStamp.txt");
18 | if (File.Exists(fileName))
19 | {
20 | DateTime LastOpenedTime = DateTime.Parse(File.ReadAllText(fileName));
21 | File.WriteAllText(fileName, DateTime.UtcNow.ToString());
22 | LsbTankPage.LastOpenedTime = LastOpenedTime;
23 | }
24 | else
25 | {
26 | File.WriteAllText(fileName, DateTime.UtcNow.ToString());
27 | LsbTankPage.LastOpenedTime = DateTime.UtcNow;
28 | }
29 |
30 | MainPage = new NavigationPage(new MainPage());
31 | }
32 |
33 | protected override async void OnStart()
34 | {
35 | await DependencyService.Get().RequestPermissions(); //申请权限
36 | }
37 |
38 | protected override void OnSleep()
39 | {
40 | LsbTankPage.IsBackstage = true;
41 | }
42 |
43 | protected override void OnResume()
44 | {
45 | LsbTankPage.IsBackstage = false;
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/WarFactory/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using Xamarin.Forms.Xaml;
2 |
3 | [assembly: XamlCompilation(XamlCompilationOptions.Compile)]
--------------------------------------------------------------------------------
/WarFactory/FactoryFunc/LsbTank.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Reflection;
4 | using System.Collections.Generic;
5 | using SkiaSharp;
6 | using System.Text;
7 | using MimeMapping;
8 |
9 | namespace WarFactory.FactoryFunc
10 | {
11 | class LsbTank
12 | {
13 | static public MemoryStream Encode(FileStream surPicFile, FileStream insPicFile, string info, int compress)
14 | {
15 | if (compress == 0 || compress >= 8) return null;
16 |
17 | byte[] lsbMask = { 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F };
18 | char[] signature = "/By:f_Endman".ToCharArray();
19 |
20 | long insPicLength = insPicFile.Length;
21 |
22 | SKBitmap surPic = SKBitmap.Decode(surPicFile);
23 |
24 | //得到隐写里图所需的表图的尺寸,并缩放表图
25 | long byteForLSB = insPicLength * 8 / compress; //隐写所有里数据所需的表图字节数
26 | long currentSurPicByte = surPic.Width * surPic.Height * 3;//表图现有的可用于LSB隐写的字节数
27 | double zoom = (double)byteForLSB / (double)currentSurPicByte * ((compress >= 6) ? 1.05d : 1.01d); //表图需要缩放的倍数(留出1%-5%余量)
28 | /* 问题可转化为两矩形已知前后面积比例zoom,前者宽度高度a1,b1和a1/b1,并且两矩形长宽比相同即a1/b1=a2/b2;求后者矩形的长a2与宽b2 *
29 | * ∵a1/b1=a2/b2 ∴a2=a1/b1*b2 又∵a1*b1*zoom=a2*b2 ∴联立可解得b2=b1*根号zoom ∴a2=a1*根号zoom */
30 | double squareRootZoom = Math.Sqrt(zoom);
31 | SKBitmap tankPic = new SKBitmap((int)(surPic.Width * squareRootZoom), (int)(surPic.Height * squareRootZoom), SKColorType.Bgra8888, SKAlphaType.Premul);
32 | surPic.ScalePixels(tankPic, SKFilterQuality.High);
33 |
34 | //为表图添加水印
35 | SKPaint paint = new SKPaint
36 | {
37 | Color = SKColors.Black,
38 | TextSize = 24,
39 | IsAntialias = true, //抗锯齿
40 | Typeface = SKTypeface.FromStream(Assembly.GetExecutingAssembly().GetManifestResourceStream("WarFactory.Resources.simhei.ttf")) //使用内嵌的字体
41 | };
42 | SKRect textSize = new SKRect();
43 | paint.MeasureText(info, ref textSize); //得到文字的尺寸
44 | int textWidth = (int)(textSize.Size.Width + 2);
45 | if (textWidth > tankPic.Width) textWidth = tankPic.Width;
46 | SKBitmap infoPic = new SKBitmap(textWidth, 30); //创建水印
47 | SKCanvas canvas = new SKCanvas(infoPic);
48 | canvas.DrawColor(SKColors.White);
49 | canvas.DrawText(info, 0, (30 - textSize.Size.Height) / 2 - textSize.Top, paint);
50 | byte alpha = 0xCF; //水印不透明度
51 | for (int i = 0; i < infoPic.Height; i++) //混色
52 | {
53 | for (int j = 0; j < infoPic.Width; j++)
54 | {
55 | SKColor infoColor = infoPic.GetPixel(j, i);
56 | SKColor surColor = tankPic.GetPixel(j, i);
57 | byte red = (byte)((infoColor.Red * alpha + surColor.Red * (0xFF - alpha)) / 0xFF);
58 | byte green = (byte)((infoColor.Green * alpha + surColor.Green * (0xFF - alpha)) / 0xFF);
59 | byte blue = (byte)((infoColor.Blue * alpha + surColor.Blue * (0xFF - alpha)) / 0xFF);
60 | tankPic.SetPixel(j, i, new SKColor(red, green, blue));
61 | }
62 | }
63 |
64 | //写入里数据文件头(根据网页源码以及WinHex亲测推测)
65 | /* 结构如下:
66 | * 里数据大小(字符串格式)
67 | * '\1'
68 | * 里文件名称
69 | * '\1'
70 | * 里文件格式(特定字符串):目前我见过的原作者写的有"image/jpeg"和"image/png"和"image/png"三种,这个应该是关系到网页版解码后显示(我本业是嵌入式,让我完全弄明白这玩意就是难为我QWQ)
71 | * '\0'
72 | */
73 | List insPicByteList = new List();
74 | char[] insPicLengthStr = insPicLength.ToString().ToCharArray();
75 | for (int i = 0; i < insPicLengthStr.Length; i++)
76 | insPicByteList.Add((byte)insPicLengthStr[i]);
77 |
78 | insPicByteList.Add(0x01);
79 |
80 | char[] insPicLengthFileName = insPicFile.Name.Substring(insPicFile.Name.LastIndexOf("/") + 1).ToCharArray(); //获取包含扩展名的文件名
81 | for (int i = 0; i < insPicLengthFileName.Length; i++)
82 | insPicByteList.Add((byte)insPicLengthFileName[i]);
83 |
84 | insPicByteList.Add(0x01);
85 |
86 | char[] insMime;
87 | insMime = MimeUtility.GetMimeMapping(insPicFile.Name).ToCharArray();
88 |
89 | for (int i = 0; i < insMime.Length; i++)
90 | insPicByteList.Add((byte)insMime[i]);
91 |
92 | insPicByteList.Add(0x00);
93 |
94 | //读取里数据
95 | byte[] insPicByte = new byte[insPicFile.Length];
96 | insPicFile.Read(insPicByte, 0, (int)insPicFile.Length);
97 | insPicFile.Seek(0, SeekOrigin.Begin);
98 | insPicByteList.AddRange(new List(insPicByte));
99 |
100 | //BGRA转RGB
101 | SKColor[] tankColorArray = tankPic.Pixels;
102 | byte[] tankByteArray = new byte[tankColorArray.Length * 3];
103 | for (int i = 0; i < tankColorArray.Length; i++)
104 | {
105 | tankByteArray[i * 3 + 0] = (tankColorArray[i].Red);
106 | tankByteArray[i * 3 + 1] = (tankColorArray[i].Green);
107 | tankByteArray[i * 3 + 2] = (tankColorArray[i].Blue);
108 | }
109 |
110 | //前三个字节为数据标识保留(根据网页源码推测)
111 | /* 原图数据前三个字节推测如下:
112 | * Byte[0]:低3位固定为0x0
113 | * Byte[1]:低3位固定为0x3
114 | * Byte[2]:低3位数据为LSB隐写的位数,对应网页版的压缩度 1 <= (Byte[2] & 0x7) <= 4
115 | */
116 | tankByteArray[0] &= 0xF8;
117 | tankByteArray[0] |= 0x00;
118 | tankByteArray[1] &= 0xF8;
119 | tankByteArray[1] |= 0x03;
120 | tankByteArray[2] &= 0xF8;
121 | tankByteArray[2] |= (byte)(compress & 0x7);
122 |
123 | //---LSB隐写,具体细节很繁琐,用到了一堆位运算---//
124 | int Count = 0, snCount = 0;
125 | Int32 FIFO = 0; //先进先出,用于缓存LSB
126 | int FifoCount = 0; //FIFO中剩余的要写入的LSB的数量
127 | byte[] insPicByteArray = insPicByteList.ToArray(); //直接用List速度比较慢
128 | insPicByteList.Clear();
129 | for (int i = 3; i < tankByteArray.Length; i++)
130 | {
131 | if (FifoCount < compress) //FIFO不够写了就读一个字节
132 | {
133 | //无影坦克的LSB是大端的,所以从"左"取数据,即先取高位
134 | //如果里数据已经全部写入,就填充签名字符串
135 | FIFO |= (Int32)(((Count < insPicByteArray.Length) ? insPicByteArray[Count++] : (byte)signature[snCount++ % signature.Length]) << (/* 32 - 8 */ 24 - FifoCount));
136 | FifoCount += 8;
137 | }
138 | tankByteArray[i] &= (byte)~lsbMask[compress - 1]; //清除低n位
139 | //无影坦克的LSB是大端的,所以从"左"取数据,即先取高位
140 | tankByteArray[i] |= (byte)((FIFO >> (32 - compress)) & lsbMask[compress - 1]);
141 | FIFO <<= compress;
142 | FifoCount -= compress;
143 | }
144 |
145 | for (int i = 0; i < tankColorArray.Length; i++)
146 | tankColorArray[i] = new SKColor(tankByteArray[i * 3 + 0], tankByteArray[i * 3 + 1], tankByteArray[i * 3 + 2]);
147 | tankPic.Pixels = tankColorArray;
148 |
149 | byte[] tankPicArray = tankPic.Encode(SKEncodedImageFormat.Png, 100).ToArray();
150 |
151 | surPicFile.Close();
152 | surPicFile.Dispose();
153 | insPicFile.Close();
154 | insPicFile.Dispose();
155 |
156 | return new MemoryStream(tankPicArray);
157 | }
158 |
159 | static public MemoryStream Decode(FileStream tankPicFile, out string lsbFileName)
160 | {
161 | byte[] lsbMask = { 0x1, 0x3, 0x7, 0xF, 0x1F, 0x3F, 0x7F };
162 | lsbFileName = "";
163 |
164 | SKBitmap sPic = SKBitmap.Decode(tankPicFile);
165 | if (sPic == null) return null;
166 |
167 | SKColor[] sPicColorArray = sPic.Pixels;
168 | byte[] sPicByteArray = new byte[sPicColorArray.Length * 3];
169 |
170 | //读取所有像素的RGB字节
171 | for (int i = 0; i < sPicColorArray.Length; i++)
172 | {
173 | sPicByteArray[3 * i + 0] = sPicColorArray[i].Red;
174 | sPicByteArray[3 * i + 1] = sPicColorArray[i].Green;
175 | sPicByteArray[3 * i + 2] = sPicColorArray[i].Blue;
176 | }
177 |
178 | //前三个字节为数据标识保留(根据网页源码推测),因此从第三字节开始读取LSB数据
179 | /* 原图数据前三个字节推测如下:
180 | * Byte[0]:低3位固定为0x0
181 | * Byte[1]:低3位固定为0x3
182 | * Byte[2]:低3位数据为LSB隐写的位数,对应网页版的压缩度 1 <= (Byte[2] & 0x7) <= 7
183 | */
184 | if ((sPicByteArray[0] & 0x7) != 0x0 ||
185 | (sPicByteArray[1] & 0x7) != 0x3 ||
186 | (sPicByteArray[2] & 0x7) == 0 ||
187 | (sPicByteArray[2] & 0x7) > 7)
188 | return null;
189 | int lsbCompress = sPicByteArray[2] & 0x7;
190 |
191 | //反正就是把LSB数据都读出来了,具体细节很繁琐,用到了一堆位运算
192 | int FIFO = 0; //先进先出,用于缓存LSB
193 | int FifoCount = 0; //已经读取的LSB数量
194 | List lsbByte = new List();
195 | for (int i = 2; i < sPicByteArray.Length; i++)
196 | {
197 | FIFO |= (sPicByteArray[i]) & lsbMask[lsbCompress - 1];
198 | if (FifoCount >= 8) //已经读取了一个字节
199 | {
200 | lsbByte.Add((byte)((FIFO >> (FifoCount - 8)) & 0xFF));
201 | FifoCount -= 8;
202 | }
203 | FIFO <<= lsbCompress;
204 | FifoCount += lsbCompress;
205 | }
206 |
207 | //循环检测至少256个字节来获取LSB文件信息
208 | string sLsbCount = "", lsbFileMime = "";
209 | List lsbFileNameList = new List();
210 | int offset = 0;
211 | while (offset < 0xFF)
212 | {
213 | if (lsbByte[offset] != 0x01) sLsbCount += (char)lsbByte[offset];
214 | else break;
215 | offset++;
216 | }
217 | offset++;
218 | while (offset < 0xFF)
219 | {
220 | if (lsbByte[offset] != 0x01) lsbFileNameList.Add(lsbByte[offset]);
221 | else break;
222 | offset++;
223 | }
224 | lsbFileName = Encoding.UTF8.GetString(lsbFileNameList.ToArray()); //UTF8转ASCII
225 | offset++;
226 | while (offset < 0xFF)
227 | {
228 | if (lsbByte[offset] != 0x00) lsbFileMime += (char)lsbByte[offset];
229 | else break;
230 | offset++;
231 | }
232 | if (offset == 0xFF) return null;
233 | offset++;
234 |
235 | if(int.TryParse(sLsbCount, out int LsbCount) == false)return null;
236 | byte[] lsbByteArray = lsbByte.GetRange(offset, LsbCount).ToArray();
237 |
238 | tankPicFile.Close();
239 | tankPicFile.Dispose();
240 |
241 | return new MemoryStream(lsbByteArray);
242 | }
243 | }
244 | }
245 |
--------------------------------------------------------------------------------
/WarFactory/FactoryFunc/MirageTank.cs:
--------------------------------------------------------------------------------
1 | using SkiaSharp;
2 |
3 | namespace WarFactory.FactoryFunc
4 | {
5 | class MirageTank
6 | {
7 | static public SKBitmap Encode(ref SKBitmap photo1, ref SKBitmap photo2, float photo1K, float photo2K, byte threshold)
8 | {
9 | //灰度处理
10 | SKColor[] photo1ColorArray = null;
11 | photo1ColorArray = photo1.Pixels;
12 | for (int i = 0; i < photo1ColorArray.Length; i++)
13 | {
14 | int tmpValue = (int)(GetGrayNumColor(photo1ColorArray[i]) * photo1K);
15 | if (tmpValue < threshold + 1) tmpValue = threshold + 1;
16 | if (tmpValue > 254) tmpValue = 254;
17 | photo1ColorArray[i] = new SKColor((byte)tmpValue, (byte)tmpValue, (byte)tmpValue);
18 | }
19 | photo1.Pixels = photo1ColorArray;
20 |
21 | SKColor[] photo2ColorArray = null;
22 | photo2ColorArray = photo2.Pixels;
23 | for (int i = 0; i < photo2ColorArray.Length; i++)
24 | {
25 | int tmpValue = (int)(GetGrayNumColor(photo2ColorArray[i]) * photo2K);
26 | if (tmpValue > threshold) tmpValue = threshold;
27 | if (tmpValue < 1) tmpValue = 1;
28 | photo2ColorArray[i] = new SKColor((byte)tmpValue, (byte)tmpValue, (byte)tmpValue);
29 | }
30 | photo2.Pixels = photo2ColorArray;
31 |
32 | //调整图像大小
33 | int height = 0, width = 0;
34 | if (photo1.Height != photo2.Height || photo1.Width != photo2.Width)
35 | {
36 | if (photo1.Height > photo2.Height) height = photo1.Height;
37 | else height = photo2.Height;
38 | if (photo1.Width > photo2.Width) width = photo1.Width;
39 | else width = photo2.Width;
40 | }
41 | else
42 | {
43 | width = photo1.Width;
44 | height = photo1.Height;
45 | }
46 | float aspectRatio = width / height; //高宽比
47 | if (aspectRatio > photo1.Width / photo1.Height) //根据高宽比拉伸图像
48 | photo1 = photo1.Resize(new SKSizeI(photo1.Width * height / photo1.Height, height), SKFilterQuality.High);
49 | else
50 | photo1 = photo1.Resize(new SKSizeI(width, photo1.Height * width / photo1.Width), SKFilterQuality.High);
51 | if (aspectRatio > photo2.Width / photo2.Height) //根据高宽比拉伸图像
52 | photo2 = photo2.Resize(new SKSizeI(photo2.Width * height / photo2.Height, height), SKFilterQuality.High);
53 | else
54 | photo2 = photo2.Resize(new SKSizeI(width, photo2.Height * width / photo2.Width), SKFilterQuality.High);
55 | SKBitmap photo1Temp = new SKBitmap(width, height);
56 | SKBitmap photo2Temp = new SKBitmap(width, height);
57 | SKCanvas photo1Canvas = new SKCanvas(photo1Temp);
58 | SKCanvas photo2Canvas = new SKCanvas(photo2Temp);
59 | photo1Canvas.DrawColor(SKColors.LightGray);
60 | photo2Canvas.DrawColor(SKColors.DimGray);
61 | photo1Canvas.DrawBitmap(photo1, width / 2 - photo1.Width / 2, height / 2 - photo1.Height / 2);
62 | photo2Canvas.DrawBitmap(photo2, width / 2 - photo2.Width / 2, height / 2 - photo2.Height / 2);
63 | photo1ColorArray = photo1Temp.Pixels;
64 | photo2ColorArray = photo2Temp.Pixels;
65 |
66 | /* /!/装配坦克/!/ */
67 | SKBitmap photoTank = new SKBitmap(width, height);
68 | SKColor[] photoTankColorArray = new SKColor[width * height];
69 | for (int i = 0; i < width * height; i++)
70 | {
71 | int pixel1 = photo1ColorArray[i].Red;
72 | int pixel2 = photo2ColorArray[i].Red;
73 |
74 | int alpha = 255 - (pixel1 - pixel2);
75 | int gray = (int)(255 * pixel2 / alpha);
76 | if (gray > 255) gray = 255;
77 |
78 | photoTankColorArray[i] = new SKColor((byte)gray, (byte)gray, (byte)gray, (byte)alpha);
79 | }
80 | photoTank.Pixels = photoTankColorArray;
81 |
82 | return photoTank;
83 | }
84 |
85 | static private int GetGrayNumColor(SKColor codecolor)
86 | {
87 | //return (codecolor.Red * 19595 + codecolor.Green * 38469 + codecolor.Blue * 7472) >> 16;
88 | return (int)((float)codecolor.Red * 0.229f + (float)codecolor.Green * 0.587f + (float)codecolor.Blue * 0.114f);
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/WarFactory/MainPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
25 |
31 |
41 |
47 |
58 |
69 |
76 |
83 |
91 |
92 |
93 |
94 |
--------------------------------------------------------------------------------
/WarFactory/MainPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Xamarin.Forms;
3 | using WarFactory.ViewPage;
4 | using WarFactory.MyInterface;
5 |
6 | namespace WarFactory
7 | {
8 | public partial class MainPage : ContentPage
9 | {
10 | public MainPage()
11 | {
12 | InitializeComponent();
13 | MirageTankButton.Source = ImageSource.FromResource("WarFactory.Resources.MirageTank.png");
14 | LsbTankButton.Source = ImageSource.FromResource("WarFactory.Resources.LsbTank.png");
15 | LabelVersion.Text = DependencyService.Get().GetVersion();
16 | }
17 |
18 | private async void MirageTankButton_Clicked(object sender, EventArgs e)
19 | {
20 | await Navigation.PushAsync(new MirageTankPage());
21 | }
22 |
23 | private async void LsbTankButton_Clicked(object sender, EventArgs e)
24 | {
25 | await Navigation.PushAsync(new LsbTankPage());
26 | }
27 |
28 | private async void Button1_Clicked(object sender, EventArgs e)
29 | {
30 | await Navigation.PushAsync(new VersionPage());
31 | }
32 |
33 | private async void Button2_Clicked(object sender, EventArgs e)
34 | {
35 | await Navigation.PushAsync(new AboutPage());
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/WarFactory/MyInterface/IPlatformInterface.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Threading.Tasks;
4 | using System.Collections.Generic;
5 | using System.Text;
6 |
7 | namespace WarFactory.MyInterface
8 | {
9 | public interface IPlatformService
10 | {
11 | Task ImageSave(MemoryStream stream, bool compatibleMode, string fileName = null);
12 | Task RequestPermissions();
13 | string GetAbsoluteSavePath();
14 | string GetSavePath();
15 | string GetVersion();
16 | string[] GetLatestPictures(long timestamp); //返回所有保存时间比这个时间点晚的图片
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/WarFactory/Resources/BaiduNetDisk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory/Resources/BaiduNetDisk.png
--------------------------------------------------------------------------------
/WarFactory/Resources/File.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory/Resources/File.png
--------------------------------------------------------------------------------
/WarFactory/Resources/GitHub.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory/Resources/GitHub.png
--------------------------------------------------------------------------------
/WarFactory/Resources/Images.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory/Resources/Images.png
--------------------------------------------------------------------------------
/WarFactory/Resources/LanZouYun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory/Resources/LanZouYun.png
--------------------------------------------------------------------------------
/WarFactory/Resources/LsbTank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory/Resources/LsbTank.png
--------------------------------------------------------------------------------
/WarFactory/Resources/MirageTank.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory/Resources/MirageTank.png
--------------------------------------------------------------------------------
/WarFactory/Resources/Tieba.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory/Resources/Tieba.png
--------------------------------------------------------------------------------
/WarFactory/Resources/Version.txt:
--------------------------------------------------------------------------------
1 | Version 1.6
2 | 2021-06-26
3 | 目前为止最大的功能性更新
4 | 无影现形加入高级功能:
5 | 1.捕获模式:开启后可以切到后台下载图片,过程中新增的图片都会被添加进要现形的队列!
6 | 2.一键添加新图:点击后会一键添加自上次打开应用以来新增的图片到要现形的队列!
7 | 调整了UI
8 |
9 | Version 1.5.1
10 | 2021-06-25
11 | 大调了安卓的图片保存接口,应该能解决之前的保存崩溃问题
12 | 调整了UI
13 |
14 | Version 1.5
15 | 2021-06-23
16 | 改良了生成无影坦克的算法,现在1-7压缩度的图都能生成(6和7属于测试,兼容性稳定性都很差)
17 | 改进了UI
18 |
19 | Version 1.4
20 | 2021-06-21
21 | 添加了无影生成时表图里图的多选批量生成
22 |
23 | Version 1.3.2
24 | 2021-06-21
25 | 修复了无影现形时可能引起闪退的中文文件名乱码问题
26 | 添加了主界面右下角软件版本的显示
27 |
28 | Version 1.3.1
29 | 2021-06-19
30 | 修改了幻影图的生成:
31 | 现在表图里图高宽比不一样的时候会保持原高宽比居中拉伸
32 | 减轻了幻影图色差过大时出现黑色条纹的现象
33 |
34 | Version 1.3
35 | 2021-06-19
36 | 添加了对左上角的水印的自定义功能
37 | 暂时解决了证书问题
38 | 增加了微信赞赏界面,因此出于隐私问题隐藏了该GitHub储存库的大部分文件,只保留了关键算法和UI部分,从今往后该解决方案将不再能直接打开,需要专业人士自行移植到自己的解决方案里,还望体谅
39 |
40 | Version 1.2
41 | 2021-05-16
42 | 修复了图片保存后相册中找不到的Bug
43 |
44 | Version 1.1
45 | 2021-04-24
46 | 做了许多调整,包括但不仅限于
47 | 1.调整UI
48 | 幻影坦克工厂将亮度系数以及阈值的调整移入了一个新界面
49 | 查看大图界面添加了滚动功能,可以浏览较长的图片
50 | 2.无影坦克现形现在可以选择多张图片进行解码了(直接全选相册,High到不行),非图片文件增加了图标显示,大部分图片无需保存即可直接查看,其他文件可保存后即可点击打开
51 | 3.优化了算法,现在能够解码压缩度为5的坦克图了(之前不知道还有这个)
52 | 4.修复了若干Bug,包括但不仅限于:
53 | 第一次打开应用直接解无影坦克而导致闪退的问题
54 | 生成幻影坦克时的闪退问题
55 | 有损坏的图进行解码会导致闪退的问题
56 | …………
57 |
58 | Version 1.0
59 | 2021-04-18
60 | 软件发布,基本实现幻影坦克和无影坦克的编解码,尚存在一些Bug
61 |
62 | 附录
63 | 2021-06-25
64 | iOS已经在模拟器上开发好了
65 | 但我没有Apple开发者账号,这玩意是要花钱的,如此一来我就没法分发,也就发不上来了
66 | 再加上我的iOS开发环境极度恶劣(本人无任何苹果设备只能在Windows上运行的Mac模拟器上再运行iOS模拟器,帧数高达2帧!)
67 | 再加上iOS那个极其离谱的Photos框架,我的耐心已经被消磨殆尽了Orz。。估计以后也不会再有iOS开发计划了QAQ。。
68 |
--------------------------------------------------------------------------------
/WarFactory/Resources/WeiYun.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory/Resources/WeiYun.png
--------------------------------------------------------------------------------
/WarFactory/Resources/simhei.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/WarFactory/Resources/simhei.ttf
--------------------------------------------------------------------------------
/WarFactory/ViewPage/AboutPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
16 |
22 |
28 |
38 |
48 |
58 |
68 |
78 |
89 |
94 |
99 |
104 |
105 |
106 |
107 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/AboutPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using Xamarin.Forms;
8 | using Xamarin.Forms.Xaml;
9 | using Xamarin.Essentials;
10 |
11 | namespace WarFactory.ViewPage
12 | {
13 | [XamlCompilation(XamlCompilationOptions.Compile)]
14 | public partial class AboutPage : ContentPage
15 | {
16 | public AboutPage()
17 | {
18 | InitializeComponent();
19 | Button1.ImageSource = ImageSource.FromResource("WarFactory.Resources.GitHub.png");
20 | Button2.ImageSource = ImageSource.FromResource("WarFactory.Resources.Tieba.png");
21 | Button3.ImageSource = ImageSource.FromResource("WarFactory.Resources.LanZouYun.png");
22 | Button4.ImageSource = ImageSource.FromResource("WarFactory.Resources.WeiYun.png");
23 | Button5.ImageSource = ImageSource.FromResource("WarFactory.Resources.BaiduNetDisk.png");
24 | }
25 | private async void Button1_Clicked(object sender, EventArgs e)
26 | {
27 | await Browser.OpenAsync("https://github.com/fEndman/WarFactory");
28 | }
29 |
30 | private async void Button2_Clicked(object sender, EventArgs e)
31 | {
32 | await Browser.OpenAsync("https://tieba.baidu.com/p/7308042884");
33 | }
34 |
35 | private async void Button3_Clicked(object sender, EventArgs e)
36 | {
37 | await Browser.OpenAsync("https://wwr.lanzoui.com/b02c6ntib");
38 | }
39 |
40 | private async void Button4_Clicked(object sender, EventArgs e)
41 | {
42 | await Browser.OpenAsync("https://share.weiyun.com/yvkPZ89G");
43 | }
44 |
45 | private async void Button5_Clicked(object sender, EventArgs e)
46 | {
47 | await Browser.OpenAsync("https://pan.baidu.com/s/1B9Aw7J_cKA6W5GwNodRzPA");
48 | }
49 |
50 | private async void Button6_Clicked(object sender, EventArgs e)
51 | {
52 | await Navigation.PushAsync(new PayPage());
53 | }
54 | }
55 | }
--------------------------------------------------------------------------------
/WarFactory/ViewPage/CourseForLsbTank.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
25 |
29 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/CourseForLsbTank.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using Xamarin.Forms;
8 | using Xamarin.Forms.Xaml;
9 |
10 | namespace WarFactory.ViewPage
11 | {
12 | [XamlCompilation(XamlCompilationOptions.Compile)]
13 | public partial class CourseForLsbTank : ContentPage
14 | {
15 | public CourseForLsbTank()
16 | {
17 | InitializeComponent();
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/WarFactory/ViewPage/CourseForMirageTank.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/CourseForMirageTank.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using Xamarin.Forms;
8 | using Xamarin.Forms.Xaml;
9 |
10 | namespace WarFactory.ViewPage
11 | {
12 | [XamlCompilation(XamlCompilationOptions.Compile)]
13 | public partial class CourseForMirageTank : ContentPage
14 | {
15 | public CourseForMirageTank()
16 | {
17 | InitializeComponent();
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/WarFactory/ViewPage/ImageListPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
11 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
26 |
30 |
31 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/ImageListPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | using Xamarin.Forms;
9 | using Xamarin.Forms.Xaml;
10 | using WarFactory.ViewPage;
11 | using System.Collections.ObjectModel;
12 | using WarFactory.MyInterface;
13 | using Xamarin.Essentials;
14 |
15 | namespace WarFactory.ViewPage
16 | {
17 | public class ImageObj
18 | {
19 | public ImageObj(ImageSource imgSource, MemoryStream file, string name)
20 | {
21 | ImgSource = imgSource;
22 | File = file;
23 | Name = name;
24 | }
25 |
26 | public ImageSource ImgSource { get; set; }
27 | public MemoryStream File { get; set; }
28 | public string Name { get; set; }
29 | }
30 |
31 |
32 | [XamlCompilation(XamlCompilationOptions.Compile)]
33 | public partial class ImageListPage : ContentPage
34 | {
35 | List imageObjs = new List();
36 |
37 | public ImageListPage(List insideFile)
38 | {
39 | InitializeComponent();
40 |
41 | foreach (SInsideFile insFile in insideFile)
42 | {
43 | ImageSource tempSource = null;
44 |
45 | string extension = insFile.Name.Substring(insFile.Name.LastIndexOf(".") + 1).ToLower();
46 | if (extension == "png" || extension == "jpg" || extension == "jpeg" || extension == "bmp" || extension == "gif")
47 | tempSource = ImageSource.FromStream(() => new MemoryStream(insFile.File.ToArray()));
48 | else
49 | tempSource = ImageSource.FromResource("WarFactory.Resources.File.png");
50 |
51 | imageObjs.Add(new ImageObj(tempSource, insFile.File, insFile.Name));
52 | }
53 |
54 | imageView.ItemsSource = imageObjs;
55 |
56 | imageView.ItemTapped += eItemTapped;
57 | }
58 |
59 | private async void eItemTapped(object sender, ItemTappedEventArgs e)
60 | {
61 |
62 | ImageObj img = e.Item as ImageObj;
63 |
64 | string extension = img.Name.Substring(img.Name.LastIndexOf(".") + 1).ToLower();
65 | if (extension == "png" || extension == "jpg" || extension == "jpeg" || extension == "bmp")
66 | await Navigation.PushAsync(new ImagePage(img.File));
67 | else
68 | {
69 | string fileName = Path.Combine(DependencyService.Get().GetAbsoluteSavePath(), img.Name);
70 | if (File.Exists(fileName) == false)
71 | await DisplayAlert("警告", "这个文件需要先保存才能打开!", "确认");
72 | else
73 | await Launcher.OpenAsync(new OpenFileRequest { File = new ReadOnlyFile(fileName) });
74 | }
75 | }
76 | }
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/ImagePage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
16 |
17 |
18 |
19 |
20 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/ImagePage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 |
8 | using Xamarin.Forms;
9 | using Xamarin.Forms.Xaml;
10 | using Xamarin.Essentials;
11 |
12 | namespace WarFactory.ViewPage
13 | {
14 | [XamlCompilation(XamlCompilationOptions.Compile)]
15 | public partial class ImagePage : ContentPage
16 | {
17 | public ImagePage(MemoryStream photoStream)
18 | {
19 | InitializeComponent();
20 | Image1.Source = ImageSource.FromStream(() => new MemoryStream(photoStream.ToArray()));
21 | }
22 |
23 | private void Switch1_Toggled(object sender, ToggledEventArgs e)
24 | {
25 | if (Switch1.IsToggled)
26 | {
27 | Image1.BackgroundColor = Color.Black;
28 | this.BackgroundColor = Color.Black;
29 | }
30 | else
31 | {
32 | Image1.BackgroundColor = Color.White;
33 | this.BackgroundColor = Color.White;
34 | }
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/WarFactory/ViewPage/LsbTankAdvancedFunctionPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
16 |
20 |
26 |
27 |
37 |
41 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/LsbTankAdvancedFunctionPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using WarFactory.MyInterface;
8 | using Xamarin.Essentials;
9 | using Xamarin.Forms;
10 | using Xamarin.Forms.Xaml;
11 |
12 | namespace WarFactory.ViewPage
13 | {
14 | [XamlCompilation(XamlCompilationOptions.Compile)]
15 | public partial class LsbTankAdvancedFunctionPage : ContentPage
16 | {
17 | LsbTankPage page = null;
18 |
19 | public LsbTankAdvancedFunctionPage(LsbTankPage myPage, bool isCaptureMode)
20 | {
21 | InitializeComponent();
22 | BackgroundColor = Color.AliceBlue;
23 |
24 | Switch1.IsToggled = isCaptureMode;
25 | page = myPage;
26 | }
27 |
28 | private void Button_Clicked_1(object sender, EventArgs e)
29 | {
30 | string[] fileNames = DependencyService.Get().GetLatestPictures(Convert.ToInt64((LsbTankPage.LastOpenedTime - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds));
31 | foreach (string fileName in fileNames)
32 | page.AddTankPicture(new FileResult(fileName));
33 | DisplayAlert("完成", "已添加自上次打开应用(" + LsbTankPage.LastOpenedTime.ToLocalTime().ToString("yyyy.MM.dd HH:mm:ss") + ")以来新增的" + fileNames.Length.ToString() + "张图片到要现形的队列!", "确认");
34 | Navigation.PopAsync();
35 | }
36 |
37 | private void Switch1_Toggled(object sender, ToggledEventArgs e)
38 | {
39 | LsbTankPage.CaptureMode = Switch1.IsToggled;
40 | if (Switch1.IsToggled && page != null) //page用来判断是否是在初始化
41 | {
42 | DisplayAlert("完成", "您现在可以切到后台下载图片,过程中新增的图都会被添加进要现形的队列!", "确认");
43 | page.RunScanner();
44 | Navigation.PopAsync();
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/LsbTankPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
21 |
27 |
33 |
38 |
46 |
54 |
62 |
70 |
78 |
90 |
102 |
113 |
124 |
135 |
146 |
153 |
160 |
167 |
174 |
175 |
176 |
177 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/LsbTankPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Collections.Generic;
4 | using System.Threading.Tasks;
5 | using Xamarin.Forms;
6 | using Xamarin.Forms.Xaml;
7 | using Xamarin.Essentials;
8 | using WarFactory.FactoryFunc;
9 | using WarFactory.MyInterface;
10 | using MimeMapping;
11 |
12 | namespace WarFactory.ViewPage
13 | {
14 | public struct SInsideFile
15 | {
16 | public SInsideFile(string name, MemoryStream file)
17 | {
18 | Name = name;
19 | File = file;
20 | }
21 |
22 | public string Name;
23 | public MemoryStream File;
24 | }
25 |
26 | [XamlCompilation(XamlCompilationOptions.Compile)]
27 | public partial class LsbTankPage : ContentPage
28 | {
29 | static private int compression = 4;
30 | static private bool compatibleMode;
31 | static private string info = "TK";
32 | static private bool captureMode = false;
33 | static private bool isBackstage = false;
34 | static private DateTime lastOpenedTime = DateTime.MaxValue;
35 |
36 | static public int Compression { get { return compression; } set { compression = value; } }
37 | static public bool CompatibleMode { get { return compatibleMode; } set { compatibleMode = value; } }
38 | static public string Info { get { return info; } set { info = value; } }
39 | static public bool CaptureMode { get { return captureMode; } set { captureMode = value; } }
40 | static public bool IsBackstage { get { return isBackstage; } set { isBackstage = value; } } //在APP.xaml.cs切后台事件里操作
41 | static public DateTime LastOpenedTime { get { return lastOpenedTime; } set { lastOpenedTime = value; } }
42 |
43 | private List photoFile1 = new List();
44 | private List photoFile2 = new List();
45 | private List photoFile3 = new List();
46 | List insideFile = new List();
47 |
48 | public LsbTankPage()
49 | {
50 | InitializeComponent();
51 | BackgroundColor = Color.AliceBlue;
52 |
53 | compression = 4;
54 | compatibleMode = false;
55 | info = "TK";
56 | captureMode = false;
57 | if (DeviceInfo.Platform == DevicePlatform.iOS)
58 | {
59 | LabelTips1.Text = "点击";
60 | LabelTips2.Text = "点击";
61 | LabelTips3.Text = "点击(原图保存)";
62 | compatibleMode = true;
63 | }
64 | }
65 |
66 | private async void Image1_Clicked(object sender, EventArgs e)
67 | {
68 | if (compatibleMode)
69 | {
70 | photoFile1.Clear();
71 | FileResult file = await MediaPicker.PickPhotoAsync();
72 | if (file == null)
73 | {
74 | Image1.Source = null;
75 | return;
76 | }
77 | else
78 | {
79 | photoFile1.Add(file);
80 | Image1.Source = photoFile1[0].FullPath;
81 | }
82 | }
83 | else
84 | {
85 | photoFile1.Clear();
86 | IEnumerable files = await FilePicker.PickMultipleAsync(PickOptions.Images);
87 | if (files == null)
88 | {
89 | Image1.Source = null;
90 | return;
91 | }
92 |
93 | foreach (FileResult file in files)
94 | photoFile1.Add(file);
95 | photoFile1.Reverse(); //选取器多选是先选的排在最后,我们要的是先选在前,所以颠倒排序一下
96 | if (photoFile1.Count == 1)
97 | Image1.Source = photoFile1[0].FullPath;
98 | else
99 | Image1.Source = ImageSource.FromResource("WarFactory.Resources.Images.png");
100 | }
101 |
102 | LabelTips1.Text = "";
103 | }
104 |
105 | private async void Image2_Clicked(object sender, EventArgs e)
106 | {
107 | if (compatibleMode)
108 | {
109 | photoFile2.Clear();
110 | FileResult file = await MediaPicker.PickPhotoAsync();
111 | if (file == null)
112 | {
113 | Image2.Source = null;
114 | return;
115 | }
116 | else
117 | {
118 | photoFile2.Add(file);
119 | Image2.Source = photoFile2[0].FullPath;
120 | }
121 | }
122 | else
123 | {
124 | photoFile2.Clear();
125 | IEnumerable files = await FilePicker.PickMultipleAsync(); //可选取其他文件作为里图
126 | if (files == null)
127 | {
128 | Image2.Source = null;
129 | return;
130 | }
131 |
132 | foreach (FileResult file in files)
133 | photoFile2.Add(file);
134 | photoFile2.Reverse(); //选取器多选是先选的排在最后,我们要的是先选在前,所以颠倒排序一下
135 | if (photoFile2.Count == 1)
136 | {
137 | string extension = photoFile2[0].FileName.Substring(photoFile2[0].FileName.LastIndexOf(".") + 1).ToLower();
138 | if (extension == "png" || extension == "jpg" || extension == "jpeg" || extension == "bmp" || extension == "gif")
139 | Image2.Source = photoFile2[0].FullPath;
140 | else
141 | Image2.Source = ImageSource.FromResource("WarFactory.Resources.File.png");
142 | }
143 | else
144 | Image2.Source = ImageSource.FromResource("WarFactory.Resources.Images.png");
145 | }
146 |
147 | LabelTips2.Text = "";
148 | }
149 |
150 | private async void Image3_Clicked(object sender, EventArgs e)
151 | {
152 | if (compatibleMode)
153 | {
154 | photoFile3.Clear();
155 | FileResult file = await MediaPicker.PickPhotoAsync();
156 | if (file == null)
157 | {
158 | Image3.Source = null;
159 | return;
160 | }
161 | else
162 | {
163 | photoFile3.Add(file);
164 | Image3.Source = photoFile3[0].FullPath;
165 | }
166 | }
167 | else
168 | {
169 | photoFile3.Clear();
170 | IEnumerable files = await FilePicker.PickMultipleAsync(PickOptions.Images);
171 | if (files == null)
172 | {
173 | Image3.Source = null;
174 | return;
175 | }
176 |
177 | foreach (FileResult file in files)
178 | photoFile3.Add(file);
179 | photoFile3.Reverse(); //选取器多选是先选的排在最后,我们要的是先选在前,所以颠倒排序一下
180 | if (photoFile3.Count == 1)
181 | Image3.Source = photoFile3[0].FullPath;
182 | else
183 | Image3.Source = ImageSource.FromResource("WarFactory.Resources.Images.png");
184 | }
185 |
186 | LabelTips3.Text = "";
187 | }
188 |
189 | private async void Image4_Clicked(object sender, EventArgs e)
190 | {
191 | if (insideFile.Count == 1)
192 | {
193 | string extension = (insideFile[0].Name == null) ? "png" : insideFile[0].Name.Substring(insideFile[0].Name.LastIndexOf(".") + 1).ToLower();
194 | if (extension == "png" || extension == "jpg" || extension == "jpeg" || extension == "bmp")
195 | await Navigation.PushAsync(new ImagePage(insideFile[0].File));
196 | else
197 | {
198 | string fileName = Path.Combine(DependencyService.Get().GetAbsoluteSavePath(), insideFile[0].Name);
199 | if (File.Exists(fileName) == false)
200 | await DisplayAlert("警告", "这个文件需要先保存才能打开!", "确认");
201 | else
202 | await Launcher.OpenAsync(new OpenFileRequest { File = new ReadOnlyFile(fileName) });
203 | }
204 | }
205 | else if (insideFile.Count > 1)
206 | {
207 | await Navigation.PushAsync(new ImageListPage(insideFile));
208 | }
209 | }
210 |
211 | private async void Button_Clicked_1(object sender, EventArgs e)
212 | {
213 | if (photoFile1 == null ||
214 | photoFile2 == null ||
215 | photoFile1.Count == 0 ||
216 | photoFile2.Count == 0)
217 | {
218 | await DisplayAlert("警告", "缺少图片!", "确认");
219 | return;
220 | }
221 | foreach (FileResult pf1 in photoFile1)
222 | {
223 | foreach (FileResult pf2 in photoFile2)
224 | {
225 | if (pf1.FullPath == pf2.FullPath)
226 | {
227 | await DisplayAlert("警告", "里图不能与表图重复!", "确认");
228 | return;
229 | }
230 | }
231 | }
232 |
233 | foreach (SInsideFile insFile in insideFile)
234 | insFile.File.Dispose();
235 | insideFile.Clear();
236 | LabelFileName.Text = "";
237 | Image4.Source = null;
238 |
239 | ActivityIndicator1.IsRunning = true;
240 | Button1.IsEnabled = false;
241 | Button2.IsEnabled = false;
242 |
243 | if(compression >= 6)
244 | await DisplayAlert("警告", "支持压缩度大于等于6的无影坦克的网站很少,很有可能只有本APP能够现形,并且十分不稳定,请酌情考虑是否保存!", "确认");
245 |
246 | string fileName = "Tank_" + DateTime.Now.ToLocalTime().ToString("yyyyMMdd_HHmmss");
247 | int photoIndex = 0;
248 | if ((string.IsNullOrEmpty(info) || string.IsNullOrWhiteSpace(info)) && photoFile2.Count == 1)
249 | info = "TK";
250 | await Task.Run(() =>
251 | {
252 | foreach (FileResult fr in photoFile2)
253 | {
254 | photoIndex++;
255 | MemoryStream tempStream = LsbTank.Encode(new FileStream(photoFile1[photoIndex % photoFile1.Count].FullPath, FileMode.Open),
256 | new FileStream(fr.FullPath, FileMode.Open),
257 | info + (photoFile2.Count == 1 ? "" : photoIndex.ToString()),
258 | compression);
259 | if (tempStream != null)
260 | {
261 | insideFile.Add(new SInsideFile(fileName + "_" + photoIndex.ToString() + ".png", tempStream));
262 | tempStream.Dispose();
263 | }
264 | }
265 | });
266 |
267 | LabelTips4.Text = "";
268 | if (insideFile.Count == 1)
269 | {
270 | Image4.Source = ImageSource.FromStream(() => new MemoryStream(insideFile[0].File.ToArray()));
271 | LabelFileName.Text = "成功生成!发送时记得原图发送并且关闭水印!";
272 | }
273 | else
274 | {
275 | Image4.Source = ImageSource.FromResource("WarFactory.Resources.Images.png");
276 | LabelFileName.Text = "成功生成" + insideFile.Count.ToString() + "个文件,点击进入查看列表";
277 | }
278 |
279 | if(DeviceInfo.Platform == DevicePlatform.iOS)
280 | await DisplayAlert("警告", "iOS设备似乎即使发送原图也会被压缩,这也就注定了iOS发出去的坦克图全是锤子,因此请谨慎发图!", "确认");
281 |
282 | Button1.IsEnabled = true;
283 | Button2.IsEnabled = true;
284 | ActivityIndicator1.IsRunning = false;
285 | }
286 |
287 | private async void Button_Clicked_2(object sender, EventArgs e)
288 | {
289 | if (photoFile3.Count == 0)
290 | {
291 | await DisplayAlert("警告", "请选择要现形的图片!", "确认");
292 | return;
293 | }
294 |
295 | List photo3Stream = new List();
296 | try
297 | {
298 | foreach (FileResult file in photoFile3)
299 | photo3Stream.Add(new FileStream(file.FullPath, FileMode.Open));
300 | }
301 | catch (UnauthorizedAccessException)
302 | {
303 | await DisplayAlert("警告", "权限异常!", "确认");
304 | photo3Stream.Clear();
305 | return;
306 | }
307 | catch (FileNotFoundException)
308 | {
309 | await DisplayAlert("警告", "文件不存在!", "确认");
310 | photo3Stream.Clear();
311 | return;
312 | }
313 |
314 | foreach (SInsideFile insFile in insideFile)
315 | insFile.File.Dispose();
316 | insideFile.Clear();
317 | Image4.Source = null;
318 |
319 | ActivityIndicator1.IsRunning = true;
320 | Button1.IsEnabled = false;
321 | Button2.IsEnabled = false;
322 |
323 | await Task.Run(() =>
324 | {
325 | foreach (FileStream fs in photo3Stream)
326 | {
327 | MemoryStream tempStream = LsbTank.Decode(fs, out string tempName);
328 | if (tempStream != null)
329 | {
330 | insideFile.Add(new SInsideFile(tempName, tempStream));
331 | tempStream.Dispose();
332 | }
333 | }
334 | });
335 |
336 | LabelTips4.Text = "";
337 | if (insideFile.Count == 0)
338 | {
339 | await DisplayAlert("警告", "这些图不是无影坦克!", "确认");
340 | if(MimeUtility.GetMimeMapping(photoFile3[0].FileName) != MimeUtility.GetMimeMapping(".png"))
341 | await DisplayAlert("警告", "如果确定这不是一张锤子图,请 *查看原图* 后 保存 再现形!", "确认");
342 | LabelFileName.Text = "";
343 | }
344 | else if(insideFile.Count == 1)
345 | {
346 | string extension = insideFile[0].Name.Substring(insideFile[0].Name.LastIndexOf(".") + 1).ToLower();
347 | if (extension == "png" || extension == "jpg" || extension == "jpeg" || extension == "bmp" || extension == "gif")
348 | Image4.Source = ImageSource.FromStream(() => new MemoryStream(insideFile[0].File.ToArray()));
349 | else
350 | Image4.Source = ImageSource.FromResource("WarFactory.Resources.File.png");
351 | LabelFileName.Text = insideFile[0].Name;
352 | }
353 | else
354 | {
355 | Image4.Source = ImageSource.FromResource("WarFactory.Resources.Images.png");
356 | LabelFileName.Text = "成功现形" + insideFile.Count.ToString() + "个文件,点击进入查看列表";
357 | }
358 |
359 | Button1.IsEnabled = true;
360 | Button2.IsEnabled = true;
361 | ActivityIndicator1.IsRunning = false;
362 |
363 | foreach (FileStream ms in photo3Stream)
364 | ms.Close();
365 | }
366 |
367 | private async void Button_Clicked_3(object sender, EventArgs e)
368 | {
369 | if (insideFile.Count == 0)
370 | {
371 | await DisplayAlert("警告", "请先生成图片!", "确认");
372 | }
373 | else
374 | {
375 | string tempStr =
376 | "已保存" + insideFile.Count.ToString() + "个文件至:\n" +
377 | DependencyService.Get().GetSavePath() +
378 | "\n可在 战车工厂 相册中找到\n文件名如下:";
379 |
380 | foreach (SInsideFile insFile in insideFile)
381 | {
382 | string name = await DependencyService.Get().ImageSave(insFile.File, compatibleMode, insFile.Name);
383 | tempStr += "\n" + name;
384 | }
385 |
386 | await DisplayAlert("完成", tempStr, "确认");
387 | }
388 | }
389 |
390 | private async void Button_Clicked_4(object sender, EventArgs e)
391 | {
392 | await Navigation.PushAsync(new CourseForLsbTank());
393 | }
394 |
395 | private async void Button_Clicked_5(object sender, EventArgs e)
396 | {
397 | await Navigation.PushAsync(new LsbTankSettingPage(compression, info, compatibleMode));
398 | }
399 |
400 | private async void Button_Clicked_6(object sender, EventArgs e)
401 | {
402 | await Navigation.PushAsync(new LsbTankAdvancedFunctionPage(this, captureMode));
403 | }
404 |
405 | public void RunScanner()
406 | {
407 | Task.Run(() =>
408 | {
409 | while (captureMode)
410 | {
411 | DateTime utc = new DateTime(1970, 1, 1, 0, 0, 0, 0); //UNIX时间戳
412 | long timestamp = Convert.ToInt64((DateTime.UtcNow - utc).TotalMilliseconds);
413 | while (!isBackstage && captureMode) ; //等待进入后台
414 | while (isBackstage && captureMode) ; //等待切回应用
415 | string[] newPics = DependencyService.Get().GetLatestPictures(timestamp); //获取这期间新增的图片
416 | foreach (string newPic in newPics)
417 | photoFile3.Add(new FileResult(newPic));
418 | //在主线程上刷新UI
419 | Device.BeginInvokeOnMainThread(() =>
420 | {
421 | DisplayAlert("完成", "这次在后台捕获到了" + newPics.Length.ToString() + "张图片!您可以继续下载图片或手动关闭捕获模式!", "确认");
422 | if (photoFile3.Count == 1)
423 | Image3.Source = photoFile3[0].FullPath;
424 | else if (photoFile3.Count > 1)
425 | Image3.Source = ImageSource.FromResource("WarFactory.Resources.Images.png");
426 | if (photoFile3.Count != 0)
427 | LabelTips3.Text = "";
428 | });
429 | }
430 | });
431 | }
432 |
433 | public void AddTankPicture(FileResult fileResult)
434 | {
435 | foreach (FileResult file in photoFile3)
436 | if (fileResult.FullPath == file.FullPath)
437 | return;
438 | photoFile3.Add(fileResult);
439 |
440 | if (photoFile3.Count == 1)
441 | Image3.Source = photoFile3[0].FullPath;
442 | else if(photoFile3.Count > 1)
443 | Image3.Source = ImageSource.FromResource("WarFactory.Resources.Images.png");
444 | if (photoFile3.Count != 0)
445 | LabelTips3.Text = "";
446 | }
447 | }
448 | }
449 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/LsbTankSettingPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
21 |
27 |
32 |
36 |
41 |
47 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/LsbTankSettingPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using Xamarin.Essentials;
2 | using Xamarin.Forms;
3 | using Xamarin.Forms.Xaml;
4 |
5 | namespace WarFactory.ViewPage
6 | {
7 | [XamlCompilation(XamlCompilationOptions.Compile)]
8 | public partial class LsbTankSettingPage : ContentPage
9 | {
10 | public LsbTankSettingPage(int compression, string info, bool compatibleMode)
11 | {
12 | InitializeComponent();
13 | this.BackgroundColor = Color.AliceBlue;
14 |
15 | Label1.Text = "压缩度:" + compression.ToString();
16 | Stepper1.Value = compression;
17 | Entry1.Text = info;
18 | Switch1.IsToggled = compatibleMode;
19 | }
20 |
21 | private void Stepper1_ValueChanged(object sender, ValueChangedEventArgs e)
22 | {
23 | Label1.Text = "压缩度:" + ((int)Stepper1.Value).ToString();
24 | }
25 |
26 | private async void Switch1_Toggled(object sender, ToggledEventArgs e)
27 | {
28 | if (DeviceInfo.Platform == DevicePlatform.iOS && Switch1.IsToggled == false)
29 | await DisplayAlert("警告", "iOS的选择文件控件以及多选控件有问题!请保持兼容模式开启!", "确认");
30 | }
31 |
32 | override protected void OnDisappearing()
33 | {
34 | LsbTankPage.Compression = (int)Stepper1.Value;
35 | LsbTankPage.Info = Entry1.Text;
36 | LsbTankPage.CompatibleMode = Switch1.IsToggled;
37 | }
38 | }
39 | }
--------------------------------------------------------------------------------
/WarFactory/ViewPage/MirageTankPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
23 |
31 |
39 |
47 |
55 |
62 |
69 |
77 |
85 |
96 |
107 |
118 |
129 |
136 |
143 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/MirageTankPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Threading.Tasks;
4 | using Xamarin.Forms;
5 | using Xamarin.Forms.Xaml;
6 | using Xamarin.Essentials;
7 | using SkiaSharp;
8 | using WarFactory.FactoryFunc;
9 | using WarFactory.MyInterface;
10 |
11 | namespace WarFactory.ViewPage
12 | {
13 | [XamlCompilation(XamlCompilationOptions.Compile)]
14 | public partial class MirageTankPage : ContentPage
15 | {
16 | private FileResult photoFile1 = null;
17 | private FileResult photoFile2 = null;
18 |
19 | public MemoryStream photoTankStream = new MemoryStream();
20 |
21 | private static float photo1_K = 1.2f;
22 | private static float photo2_K = 0.6f;
23 | private static byte photoThreshold = 110;
24 |
25 | public static float Photo1_K { get {return photo1_K; } set { photo1_K = value; } }
26 | public static float Photo2_K { get { return photo2_K; } set { photo2_K = value; } }
27 | public static byte PhotoThreshold { get { return photoThreshold; } set { photoThreshold = value; } }
28 |
29 | public MirageTankPage()
30 | {
31 | InitializeComponent();
32 | this.BackgroundColor = Color.LightGray;
33 | }
34 |
35 | private async void Image1_Clicked(object sender, EventArgs e)
36 | {
37 | photoFile1 = await MediaPicker.PickPhotoAsync();
38 | if (photoFile1 == null)
39 | {
40 | Image1.Source = null;
41 | return;
42 | }
43 | else
44 | Image1.Source = photoFile1.FullPath;
45 |
46 | LabelTips1.Text = "";
47 | }
48 |
49 | private async void Image2_Clicked(object sender, EventArgs e)
50 | {
51 | photoFile2 = await MediaPicker.PickPhotoAsync();
52 | if (photoFile2 == null)
53 | {
54 | Image2.Source = null;
55 | return;
56 | }
57 | else
58 | Image2.Source = photoFile2.FullPath;
59 |
60 | LabelTips2.Text = "";
61 | }
62 |
63 | private async void Image5_Clicked(object sender, EventArgs e)
64 | {
65 | await Navigation.PushAsync(new ImagePage(photoTankStream));
66 | }
67 |
68 | private void Switch_Toggled(object sender, ToggledEventArgs e)
69 | {
70 | if (Switch1.IsToggled) Image5.BackgroundColor = Color.Black;
71 | else Image5.BackgroundColor = Color.White;
72 | }
73 |
74 | private async void Button_Clicked_1(object sender, EventArgs e)
75 | {
76 | MemoryStream photo1Stream = new MemoryStream();
77 | MemoryStream photo2Stream = new MemoryStream();
78 | SKBitmap photo1 = null;
79 | SKBitmap photo2 = null;
80 | SKBitmap photoTank = null;
81 |
82 | if (photoFile1 == null ||
83 | photoFile2 == null ||
84 | string.IsNullOrEmpty(photoFile1.FullPath) ||
85 | string.IsNullOrEmpty(photoFile2.FullPath))
86 | {
87 | await DisplayAlert("警告", "缺少图片!", "确认");
88 | return;
89 | }
90 | else
91 | {
92 | photo1 = SKBitmap.Decode(photoFile1.FullPath);
93 | photo2 = SKBitmap.Decode(photoFile2.FullPath);
94 | }
95 |
96 | Image3.Source = null;
97 | Image4.Source = null;
98 | Image5.Source = null;
99 |
100 | ActivityIndicator1.IsRunning = true;
101 |
102 | await Task.Run(() =>
103 | {
104 | photoTank = MirageTank.Encode(ref photo1, ref photo2, photo1_K, photo2_K, photoThreshold);
105 | });
106 |
107 | photoTankStream = new MemoryStream();
108 | photo1.Encode(photo1Stream, SKEncodedImageFormat.Png, 100);
109 | photo2.Encode(photo2Stream, SKEncodedImageFormat.Png, 100);
110 | photoTank.Encode(photoTankStream, SKEncodedImageFormat.Png, 100);
111 |
112 | LabelTips3.Text = "";
113 | Image3.Source = ImageSource.FromStream(() => new MemoryStream(photo1Stream.ToArray()));
114 | Image4.Source = ImageSource.FromStream(() => new MemoryStream(photo2Stream.ToArray()));
115 | Image5.Source = ImageSource.FromStream(() => new MemoryStream(photoTankStream.ToArray()));
116 |
117 | ActivityIndicator1.IsRunning = false;
118 | }
119 |
120 | private async void Button_Clicked_2(object sender, EventArgs e)
121 | {
122 | if (photoTankStream.Length != 0)
123 | {
124 | string path = DependencyService.Get().GetSavePath();
125 | path += await DependencyService.Get().ImageSave(photoTankStream, false);
126 | await DisplayAlert("完成", "已保存至:\n" + path + "\n可在 战车工厂 相册中找到", "确认");
127 | }
128 | else
129 | {
130 | await DisplayAlert("警告", "请先生成图片!", "确认");
131 | }
132 | }
133 |
134 | private async void Button_Clicked_3(object sender, EventArgs e)
135 | {
136 | await Navigation.PushAsync(new CourseForMirageTank());
137 | }
138 |
139 |
140 | private async void Button_Clicked_4(object sender, EventArgs e)
141 | {
142 | await Navigation.PushAsync(new MirageTankSettingPage());
143 | }
144 | }
145 | }
--------------------------------------------------------------------------------
/WarFactory/ViewPage/MirageTankSettingPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
20 |
26 |
34 |
39 |
45 |
53 |
58 |
64 |
72 |
76 |
81 |
82 |
83 |
84 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/MirageTankSettingPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | using Xamarin.Forms;
8 | using Xamarin.Forms.Xaml;
9 |
10 | namespace WarFactory.ViewPage
11 | {
12 | [XamlCompilation(XamlCompilationOptions.Compile)]
13 | public partial class MirageTankSettingPage : ContentPage
14 | {
15 | public MirageTankSettingPage()
16 | {
17 | InitializeComponent();
18 |
19 | Label1.Text = MirageTankPage.Photo1_K.ToString("F2");
20 | Label2.Text = MirageTankPage.Photo2_K.ToString("F2");
21 | Label3.Text = MirageTankPage.PhotoThreshold.ToString("F0");
22 | Slider1.Value = MirageTankPage.Photo1_K;
23 | Slider2.Value = MirageTankPage.Photo2_K;
24 | Slider3.Value = MirageTankPage.PhotoThreshold;
25 | }
26 |
27 | private void Slider1_ValueChanged(object sender, ValueChangedEventArgs e)
28 | {
29 | Label1.Text = Slider1.Value.ToString("F2");
30 | }
31 |
32 | private void Slider2_ValueChanged(object sender, ValueChangedEventArgs e)
33 | {
34 | Label2.Text = Slider2.Value.ToString("F2");
35 | }
36 |
37 | private void Slider3_ValueChanged(object sender, ValueChangedEventArgs e)
38 | {
39 | Label3.Text = Slider3.Value.ToString("F0");
40 | }
41 |
42 | override protected void OnDisappearing()
43 | {
44 | MirageTankPage.Photo1_K = (float)Slider1.Value;
45 | MirageTankPage.Photo2_K = (float)Slider2.Value;
46 | MirageTankPage.PhotoThreshold = (byte)Slider3.Value;
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/WarFactory/ViewPage/VersionPage.xaml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
12 |
13 |
14 |
15 |
16 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/WarFactory/ViewPage/VersionPage.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Reflection;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | using Xamarin.Forms;
10 | using Xamarin.Forms.Xaml;
11 |
12 | namespace WarFactory.ViewPage
13 | {
14 | [XamlCompilation(XamlCompilationOptions.Compile)]
15 | public partial class VersionPage : ContentPage
16 | {
17 | public VersionPage()
18 | {
19 | InitializeComponent();
20 |
21 | StreamReader textReader = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("WarFactory.Resources.Version.txt"));
22 | Label.Text = textReader.ReadToEnd(); ;
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/WarFactory/WarFactory.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netstandard2.0
5 | true
6 |
7 |
8 |
9 | portable
10 | true
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 | D:\Programs\Microsoft Visual Studio\2019\Community\Common7\IDE\ReferenceAssemblies\Microsoft\Framework\Xamarin.iOS\v1.0\Xamarin.iOS.dll
62 |
63 |
64 |
65 |
66 |
67 | CourseForLsbTank.xaml
68 |
69 |
70 |
71 |
72 |
73 | MSBuild:UpdateDesignTimeXaml
74 |
75 |
76 | MSBuild:UpdateDesignTimeXaml
77 |
78 |
79 | MSBuild:UpdateDesignTimeXaml
80 |
81 |
82 | MSBuild:UpdateDesignTimeXaml
83 |
84 |
85 | MSBuild:UpdateDesignTimeXaml
86 |
87 |
88 | MSBuild:UpdateDesignTimeXaml
89 |
90 |
91 | MSBuild:UpdateDesignTimeXaml
92 |
93 |
94 | MSBuild:UpdateDesignTimeXaml
95 |
96 |
97 | MSBuild:UpdateDesignTimeXaml
98 |
99 |
100 | MSBuild:UpdateDesignTimeXaml
101 |
102 |
103 | MSBuild:UpdateDesignTimeXaml
104 |
105 |
106 |
107 |
108 |
109 | MSBuild:Compile
110 |
111 |
112 |
--------------------------------------------------------------------------------
/Xamarin ico Creator/AppIcon.appiconset/Icon1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/AppIcon.appiconset/Icon1024.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/AppIcon.appiconset/Icon120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/AppIcon.appiconset/Icon120.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/AppIcon.appiconset/Icon152.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/AppIcon.appiconset/Icon152.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/AppIcon.appiconset/Icon167.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/AppIcon.appiconset/Icon167.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/AppIcon.appiconset/Icon180.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/AppIcon.appiconset/Icon180.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/AppIcon.appiconset/Icon20.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/AppIcon.appiconset/Icon20.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/AppIcon.appiconset/Icon29.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/AppIcon.appiconset/Icon29.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/AppIcon.appiconset/Icon40.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/AppIcon.appiconset/Icon40.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/AppIcon.appiconset/Icon58.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/AppIcon.appiconset/Icon58.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/AppIcon.appiconset/Icon60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/AppIcon.appiconset/Icon60.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/AppIcon.appiconset/Icon76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/AppIcon.appiconset/Icon76.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/AppIcon.appiconset/Icon80.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/AppIcon.appiconset/Icon80.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/AppIcon.appiconset/Icon87.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/AppIcon.appiconset/Icon87.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/Resources/mipmap-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/Resources/mipmap-hdpi/icon.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/Resources/mipmap-hdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/Resources/mipmap-hdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/Resources/mipmap-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/Resources/mipmap-mdpi/icon.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/Resources/mipmap-mdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/Resources/mipmap-mdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/Resources/mipmap-xhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/Resources/mipmap-xhdpi/icon.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/Resources/mipmap-xhdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/Resources/mipmap-xhdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/Resources/mipmap-xxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/Resources/mipmap-xxhdpi/icon.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/Resources/mipmap-xxhdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/Resources/mipmap-xxhdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/Resources/mipmap-xxxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/Resources/mipmap-xxxhdpi/icon.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/Resources/mipmap-xxxhdpi/launcher_foreground.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/Resources/mipmap-xxxhdpi/launcher_foreground.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/SkiaSharp.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/SkiaSharp.dll
--------------------------------------------------------------------------------
/Xamarin ico Creator/WarFactory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/WarFactory.png
--------------------------------------------------------------------------------
/Xamarin ico Creator/Xamarin ico Creator.deps.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtimeTarget": {
3 | "name": ".NETCoreApp,Version=v5.0",
4 | "signature": ""
5 | },
6 | "compilationOptions": {},
7 | "targets": {
8 | ".NETCoreApp,Version=v5.0": {
9 | "Xamarin ico Creator/1.0.0": {
10 | "dependencies": {
11 | "SkiaSharp": "2.80.2"
12 | },
13 | "runtime": {
14 | "Xamarin ico Creator.dll": {}
15 | }
16 | },
17 | "SkiaSharp/2.80.2": {
18 | "dependencies": {
19 | "System.Memory": "4.5.3"
20 | },
21 | "runtime": {
22 | "lib/netstandard2.0/SkiaSharp.dll": {
23 | "assemblyVersion": "2.80.0.0",
24 | "fileVersion": "2.80.2.0"
25 | }
26 | },
27 | "runtimeTargets": {
28 | "runtimes/osx/native/libSkiaSharp.dylib": {
29 | "rid": "osx",
30 | "assetType": "native",
31 | "fileVersion": "0.0.0.0"
32 | },
33 | "runtimes/win-arm64/native/libSkiaSharp.dll": {
34 | "rid": "win-arm64",
35 | "assetType": "native",
36 | "fileVersion": "0.0.0.0"
37 | },
38 | "runtimes/win-x64/native/libSkiaSharp.dll": {
39 | "rid": "win-x64",
40 | "assetType": "native",
41 | "fileVersion": "0.0.0.0"
42 | },
43 | "runtimes/win-x86/native/libSkiaSharp.dll": {
44 | "rid": "win-x86",
45 | "assetType": "native",
46 | "fileVersion": "0.0.0.0"
47 | }
48 | }
49 | },
50 | "System.Memory/4.5.3": {}
51 | }
52 | },
53 | "libraries": {
54 | "Xamarin ico Creator/1.0.0": {
55 | "type": "project",
56 | "serviceable": false,
57 | "sha512": ""
58 | },
59 | "SkiaSharp/2.80.2": {
60 | "type": "package",
61 | "serviceable": true,
62 | "sha512": "sha512-D25rzdCwh+3L+XyXqpNa+H/yiLJbE3/R3K/XexwHyQjGdzZvSufFW3oqf3En7hhqSIsxsJ8f5NEZ0J5W5wlGBg==",
63 | "path": "skiasharp/2.80.2",
64 | "hashPath": "skiasharp.2.80.2.nupkg.sha512"
65 | },
66 | "System.Memory/4.5.3": {
67 | "type": "package",
68 | "serviceable": true,
69 | "sha512": "sha512-3oDzvc/zzetpTKWMShs1AADwZjQ/36HnsufHRPcOjyRAAMLDlu2iD33MBI2opxnezcVUtXyqDXXjoFMOU9c7SA==",
70 | "path": "system.memory/4.5.3",
71 | "hashPath": "system.memory.4.5.3.nupkg.sha512"
72 | }
73 | }
74 | }
--------------------------------------------------------------------------------
/Xamarin ico Creator/Xamarin ico Creator.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/Xamarin ico Creator.dll
--------------------------------------------------------------------------------
/Xamarin ico Creator/Xamarin ico Creator.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/Xamarin ico Creator.exe
--------------------------------------------------------------------------------
/Xamarin ico Creator/Xamarin ico Creator.pdb:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/Xamarin ico Creator.pdb
--------------------------------------------------------------------------------
/Xamarin ico Creator/Xamarin ico Creator.runtimeconfig.dev.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtimeOptions": {
3 | "additionalProbingPaths": [
4 | "C:\\Users\\17494\\.dotnet\\store\\|arch|\\|tfm|",
5 | "C:\\Users\\17494\\.nuget\\packages",
6 | "E:\\Programs\\Microsoft Visual Studio\\Shared\\NuGetPackages",
7 | "C:\\Program Files (x86)\\Microsoft\\Xamarin\\NuGet"
8 | ]
9 | }
10 | }
--------------------------------------------------------------------------------
/Xamarin ico Creator/Xamarin ico Creator.runtimeconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "runtimeOptions": {
3 | "tfm": "net5.0",
4 | "framework": {
5 | "name": "Microsoft.NETCore.App",
6 | "version": "5.0.0"
7 | }
8 | }
9 | }
--------------------------------------------------------------------------------
/Xamarin ico Creator/ref/Xamarin ico Creator.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/ref/Xamarin ico Creator.dll
--------------------------------------------------------------------------------
/Xamarin ico Creator/runtimes/osx/native/libSkiaSharp.dylib:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/runtimes/osx/native/libSkiaSharp.dylib
--------------------------------------------------------------------------------
/Xamarin ico Creator/runtimes/win-arm64/native/libSkiaSharp.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/runtimes/win-arm64/native/libSkiaSharp.dll
--------------------------------------------------------------------------------
/Xamarin ico Creator/runtimes/win-x64/native/libSkiaSharp.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/runtimes/win-x64/native/libSkiaSharp.dll
--------------------------------------------------------------------------------
/Xamarin ico Creator/runtimes/win-x86/native/libSkiaSharp.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fEndman/WarFactory/ddaad18b3a0a39837c82461bb7f1a67cc1cb1634/Xamarin ico Creator/runtimes/win-x86/native/libSkiaSharp.dll
--------------------------------------------------------------------------------