Commit fe860d03 SK

添加项目文件。

1 个父辈 168c8f99
正在显示 47 个修改的文件 包含 2964 行增加0 行删除
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\OpenCvSharp3-AnyCPU.4.0.0.20181129\build\OpenCvSharp3-AnyCPU.props" Condition="Exists('..\packages\OpenCvSharp3-AnyCPU.4.0.0.20181129\build\OpenCvSharp3-AnyCPU.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{529F3829-BD91-42A7-95AF-9DEA2DC409CB}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>AOI</RootNamespace>
<AssemblyName>AOI</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="OpenCvSharp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6adad1e807fea099, processorArchitecture=MSIL">
<HintPath>..\packages\OpenCvSharp3-AnyCPU.4.0.0.20181129\lib\net40\OpenCvSharp.dll</HintPath>
</Reference>
<Reference Include="OpenCvSharp.Blob, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6adad1e807fea099, processorArchitecture=MSIL">
<HintPath>..\packages\OpenCvSharp3-AnyCPU.4.0.0.20181129\lib\net40\OpenCvSharp.Blob.dll</HintPath>
</Reference>
<Reference Include="OpenCvSharp.Extensions, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6adad1e807fea099, processorArchitecture=MSIL">
<HintPath>..\packages\OpenCvSharp3-AnyCPU.4.0.0.20181129\lib\net40\OpenCvSharp.Extensions.dll</HintPath>
</Reference>
<Reference Include="OpenCvSharp.UserInterface, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6adad1e807fea099, processorArchitecture=MSIL">
<HintPath>..\packages\OpenCvSharp3-AnyCPU.4.0.0.20181129\lib\net40\OpenCvSharp.UserInterface.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AoiProject.cs" />
<Compile Include="util\Base64Util.cs" />
<Compile Include="util\ImageUtil.cs" />
<Compile Include="AoiMethod.cs" />
<Compile Include="blob\AoiBlobMethod.cs" />
<Compile Include="mark\AoiMarkMethod.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ResultBean.cs" />
<Compile Include="rgb\AoiMethodRgb.cs" />
<Compile Include="util\JsonUtil.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\OpenCvSharp3-AnyCPU.4.0.0.20181129\build\OpenCvSharp3-AnyCPU.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\OpenCvSharp3-AnyCPU.4.0.0.20181129\build\OpenCvSharp3-AnyCPU.props'))" />
</Target>
</Project>
\ No newline at end of file \ No newline at end of file
using OpenCvSharp;
using OpenCvSharp.Extensions;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AOI
{
public abstract class AoiMethod
{
/// <summary>
/// 兴趣区域路径
/// </summary>
public GraphicsPath RoiPath;
public abstract ResultBean Check(Image standardImage, Image imageToCheck);
/// <summary>
/// 获取单通道的掩模图片
/// </summary>
/// <param name="img"></param>
/// <param name="path"></param>
/// <returns></returns>
public Image GetRoiMask(Image img, GraphicsPath path)
{
if (path != null)
{
var bounds = path.GetBounds();
if (bounds.Width > 0 && bounds.Height > 0)
{
Bitmap mask = new Bitmap(img.Width, img.Height);
using (Graphics g = Graphics.FromImage(mask))
{
var br = new TextureBrush(img);
g.FillPath(br, path);
}
return mask;
}
}
return null;
}
public Image GetRoiImage(Image image, GraphicsPath path, bool needCut)
{
Image maskImg = GetRoiMask(image, path);
if (maskImg != null)
{
var bounds = path.GetBounds();
int resultWidth = (int)bounds.Width;
int resultHeight = (int)bounds.Height;
var srcLocation = bounds.Location;
if (!needCut)
{
//获取带原图位置的大图
resultWidth = image.Width;
resultHeight = image.Height;
srcLocation = PointF.Empty;
}
Bitmap result = new Bitmap(resultWidth, resultHeight);
var dstRect = new RectangleF(0, 0, resultWidth, resultHeight);
var srcRect = new RectangleF(srcLocation.X, srcLocation.Y, resultWidth, resultHeight);
using (Graphics g = Graphics.FromImage(result))
{
g.DrawImage(maskImg, dstRect, srcRect, GraphicsUnit.Pixel);
}
return result;
}
return null;
}
public Image GetRoiImage(Image image, bool needCut)
{
return GetRoiImage(image, RoiPath, needCut);
}
}
}
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace AOI
{
public class AoiProject
{
public AoiProject(Image theImage)
{
this.standardImage = theImage;
}
/// <summary>
/// 标准的Image
/// </summary>
private Image standardImage { get; set; }
/// <summary>
/// 所有的AOI方法
/// </summary>
public Dictionary<string, AoiMethod> methodMap = new Dictionary<string, AoiMethod>();
public List<ResultBean> CheckAll(Image image)
{
//如果设置了校准方法,先校准图片
var markMethodMap = methodMap.Where(kv=>kv.Value is AoiMarkMethod);
foreach (var item in markMethodMap)
{
ResultBean resultBean = item.Value.Check(standardImage, image);
if (resultBean.result)
{
//校准成功
image = resultBean.currentRoiImage;
}
}
List<ResultBean> resultBeans = new List<ResultBean>();
foreach(var item in methodMap)
{
AoiMethod method = item.Value;
if(method is AoiMarkMethod)
{
//校准图片的,忽略
}
else
{
ResultBean resultBean = method.Check(standardImage, image);
resultBean.labelKey = item.Key;
resultBeans.Add(resultBean);
}
}
return resultBeans;
}
public void Save(string filePath)
{
Dictionary<string, string> projectMap = new Dictionary<string, string>();
string base64ImgStr = Base64Util.ToBase64(this.standardImage);
projectMap.Add("base64Img", base64ImgStr);
string methodMapJson = JsonUtil.SerializeObject(this.methodMap);
projectMap.Add("methodMap", methodMapJson);
JsonUtil.SerializeObjectToFile(projectMap,filePath,false);
}
public void Load(string filePath)
{
Dictionary<string, string> projectMap = JsonUtil.DeserializeJsonToObjectFromFile<Dictionary<string, string>>(filePath);
string base64Img = projectMap["base64Img"];
this.standardImage = Base64Util.ToImage(base64Img);
string methodMapJson = projectMap["methodMap"];
this.methodMap = JsonUtil.DeserializeJsonToObject<Dictionary<string, AoiMethod>>(methodMapJson);
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AOI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AOI")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("529f3829-bd91-42a7-95af-9dea2dc409cb")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AOI
{
public class ResultBean
{
/// <summary>
/// AOI标识
/// </summary>
public string labelKey;
/// <summary>
/// AOI检测结果,true表示OK, false表示NG
/// </summary>
public bool result = false;
public Image standardRoiImage;
public Image currentRoiImage;
}
}
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
using OpenCvSharp.Blob;
using OpenCvSharp.XFeatures2D;
namespace AOI
{
/// <summary>
/// 斑点分析
/// </summary>
public class AoiBlobMethod : AoiMethod
{
/// <summary>
/// 二值化时的阈值, 小于0表示自动计算阈值,绝对值为用户设定的阈值,大于0表示按用户设置的阈值进行二值化
/// </summary>
public int thresh = -1;
/// <summary>
/// 统计Blob时,使用黑色的或白色的进行统计
/// </summary>
public bool whiteOnBlack = false;
/// <summary>
/// 过滤Blob时的最少像素数
/// </summary>
public int minArea = 0;
/// <summary>
/// 过滤Blob时的最多像素数,小于0表示不限制
/// </summary>
public int maxArea = -1;
/// <summary>
/// 经过过滤后的Blob的 最小数量
/// </summary>
public int minNum = 0;
/// <summary>
/// 经过过滤后的Blob的 最大数量, 小于0表示不限制
/// </summary>
public int maxNum = -1;
public override ResultBean Check(Image standardImage, Image imageToCheck)
{
ResultBean resultBean = new ResultBean();
bool needCut = true;
Image standardRoiImg = GetRoiImage(standardImage, needCut);
resultBean.standardRoiImage = standardRoiImg;
Image currentRoiImg = GetRoiImage(imageToCheck, needCut);
resultBean.currentRoiImage = currentRoiImg;
int num = GetBlobNum(currentRoiImg, out Image dstImg, out List<CvBlob> blobList);
bool result = false;
if (num > minNum)
{
if(maxNum <= 0)
{
result = true;
}
else if(num < maxNum)
{
result = true;
}
}
resultBean.result = result;
return resultBean;
}
/// <summary>
/// 对源图像进行二值化,找出所有Blob后,根据minArea和maxArea过滤Blob后的数量
/// </summary>
/// <param name="srcImg">原始图片</param>
/// <param name="dstImg">二值化后的图片</param>
/// <param name="blobList">所有的Blob</param>
/// <returns>过滤后的Blob数量</returns>
public int GetBlobNum(Image srcImg, out Image dstImg, out List<CvBlob> blobList)
{
Mat srcMat = ImageUtil.ToMat(srcImg);
Mat threshMat = new Mat();
Cv2.CvtColor(srcMat, threshMat, ColorConversionCodes.RGB2GRAY);
ThresholdTypes threshType = ThresholdTypes.Binary;
if (whiteOnBlack)
{
threshType = ThresholdTypes.BinaryInv;
}
if (thresh < 0)
{
threshType = threshType | ThresholdTypes.Otsu;
}
Cv2.Threshold(threshMat, threshMat, thresh, 255, threshType);
CvBlobs blobs = new CvBlobs();
blobs.Label(threshMat);
blobList = blobs.Values.ToList();
dstImg = ImageUtil.ToImage(threshMat);
List<CvBlob> resultBlobs = blobList.Where(b => {
if (b.Area > minArea)
{
if (maxArea <= 0 )
{
return true;
}
else if (b.Area < maxArea)
{
return true;
}
}
return false;
}).ToList();
return resultBlobs.Count;
}
}
}
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenCvSharp;
using OpenCvSharp.XFeatures2D;
namespace AOI
{
/// <summary>
/// 从搜索区域中查找Mark区域,对图片进行校准
/// </summary>
public class AoiMarkMethod : AoiMethod
{
/// <summary>
/// 搜索区域路径
/// </summary>
public GraphicsPath SearchPath;
public override ResultBean Check(Image standardImage, Image imageToCheck)
{
ResultBean resultBean = new ResultBean();
resultBean.standardRoiImage = standardImage;
bool needCut = false;
//标准图中的Mart区域
Image markImage = GetRoiImage(standardImage, RoiPath, needCut);
//搜索区域
Image searchImage = GetRoiImage(imageToCheck, SearchPath, needCut);
if (markImage != null && searchImage != null)
{
var affine = GetAffineMat(markImage, searchImage);
if(affine != null)
{
var matToCheck = ImageUtil.ToMat(imageToCheck);
var fixedMat = FixImage(affine, matToCheck);
resultBean.result = true;
resultBean.currentRoiImage = ImageUtil.ToImage(fixedMat);
}
}
return resultBean;
}
/// <summary>
/// 校准图片
/// </summary>
/// <param name="affineMat"></param>
/// <param name="srcMat"></param>
/// <returns></returns>
private Mat FixImage(Mat affineMat, Mat srcMat)
{
Mat resultMat = new Mat();
Cv2.WarpAffine(srcMat, resultMat, affineMat, srcMat.Size());
return resultMat;
}
/// <summary>
/// 获取映射距阵
/// </summary>
/// <param name="markImage"></param>
/// <param name="srcImage"></param>
/// <returns></returns>
private Mat GetAffineMat(Image markImage, Image srcImage)
{
Mat markMat = ImageUtil.ToMat(new Bitmap(markImage));
Mat originalMat = ImageUtil.ToMat(new Bitmap(srcImage));
Mat srcMat = new Mat();
//灰度图转换
Cv2.CvtColor(markMat, markMat, ColorConversionCodes.RGB2GRAY);
Cv2.CvtColor(originalMat, srcMat, ColorConversionCodes.RGB2GRAY);
//提取特征点
SIFT sift = SIFT.Create(200);
KeyPoint[] markKeyPoints, srcKeyPoints;
MatOfFloat roiDescriptors = new MatOfFloat();
MatOfFloat srcDescriptors = new MatOfFloat();
sift.DetectAndCompute(markMat, null, out markKeyPoints, roiDescriptors);
sift.DetectAndCompute(srcMat, null, out srcKeyPoints, srcDescriptors);
var flannMatcher = new FlannBasedMatcher();
DMatch[] matchePoints = flannMatcher.Match(srcDescriptors, roiDescriptors);
//提取强特征点
double minMatch = 1;
double maxMatch = 0;
for (int i = 0; i < matchePoints.Length; i++)
{
double distance = matchePoints[i].Distance;
//匹配值最大最小值获取
if (distance < minMatch)
{
minMatch = distance;
}
if (distance > maxMatch)
{
maxMatch = distance;
}
}
List<DMatch> goodMatchePoints = new List<DMatch>();
for (int i = 0; i < matchePoints.Length; i++)
{
if (matchePoints[i].Distance < minMatch + (maxMatch - minMatch) / 4)
{
goodMatchePoints.Add(matchePoints[i]);
}
}
//获取排在前N个的最优匹配特征点
int num = goodMatchePoints.Count;
if (num >= 3)
{
num = 3;
}
else
{
//不匹配
return null;
}
List<Point2f> markPoints = new List<Point2f>();
List<Point2f> srcPoints = new List<Point2f>();
goodMatchePoints.Sort((left, right) =>
{
if (left.Distance > right.Distance)
return 1;
else if (left.Distance == right.Distance)
return 0;
else
return -1;
});
//Mat matchMat = new Mat();
//Cv2.DrawMatches(srcMat, srcKeyPoints, markMat, roiKeyPoints, goodMatchePoints.Take(num), matchMat);
//Cv2.ImShow("Match", matchMat);
for (int i = 0; i < num; i++)
{
srcPoints.Add(srcKeyPoints[goodMatchePoints[i].QueryIdx].Pt);
markPoints.Add(markKeyPoints[goodMatchePoints[i].TrainIdx].Pt);
}
//获取图像1到图像2的投影映射矩阵 尺寸为3*3
Mat affineMat = Cv2.GetAffineTransform(srcPoints, markPoints);
return affineMat;
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="12.0.2" targetFramework="net45" />
<package id="OpenCvSharp3-AnyCPU" version="4.0.0.20181129" targetFramework="net45" />
</packages>
\ No newline at end of file \ No newline at end of file
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AOI.rgb
{
/// <summary>
/// 颜色抽取
/// </summary>
public class AoiMethodRgb : AoiMethod
{
public int minR = 1;
public int maxR = 1;
public int minG = 1;
public int maxG = 255;
public int minB = 255;
public int maxB = 255;
/// <summary>
/// 抽取出的像素最小占比
/// </summary>
public float minRate = 0;
/// <summary>
/// 抽取出的像素最大占比
/// </summary>
public float maxRate = 100;
public override ResultBean Check(Image standardImage, Image imageToCheck)
{
ResultBean resultBean = new ResultBean();
bool needCut = true;
Image standardRoiImg = GetRoiImage(standardImage, needCut);
resultBean.standardRoiImage = standardRoiImg;
Image currentRoiImg = GetRoiImage(imageToCheck, needCut);
resultBean.currentRoiImage = currentRoiImg;
float rate = GetRate(currentRoiImg, out Image dstImg);
bool result = false;
if(rate >= minRate && rate <= maxRate)
{
result = true;
}
resultBean.result = result;
return resultBean;
}
public float GetRate(Image img, out Image dstImg)
{
float percent = 0;
dstImg = null;
bool needCut = true;
Image currentRoiImg = GetRoiImage(img, needCut);
if (currentRoiImg != null)
{
Mat originalRoiMat = ImageUtil.ToMat(currentRoiImg);
Mat roiMat = new Mat();
Cv2.CvtColor(originalRoiMat, roiMat, ColorConversionCodes.BGRA2BGR);
Mat dst = new Mat();
//如果不是矩形可能会把透明像素也计算进去,所以这里最小从1开始
int lowR = minR > 0 ? minR : 1;
int lowG = minG > 0 ? minG : 1;
int lowB = minB > 0 ? minB : 1;
Scalar minScalar = Scalar.FromRgb(lowR, lowG, lowB);
Scalar maxScalar = Scalar.FromRgb(maxR, maxG, maxB);
Cv2.InRange(roiMat, minScalar, maxScalar, dst);
int count = Cv2.CountNonZero(dst);
originalRoiMat.CopyTo(dst, dst);
dstImg = ImageUtil.ToImage(dst);
//计算总像素
minScalar = Scalar.FromRgb(1, 1, 1);
maxScalar = Scalar.FromRgb(255, 255, 255);
Cv2.InRange(roiMat, minScalar, maxScalar, dst);
int totalCount = Cv2.CountNonZero(dst);
percent = count * 100.0f / totalCount;
}
return percent;
}
}
}
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
namespace AOI
{
public class Base64Util
{
/// <summary>
/// 将图片数据转换为Base64字符串
/// </summary>
public static string ToBase64(Image img)
{
if (img == null)
{
return "";
}
BinaryFormatter binFormatter = new BinaryFormatter();
MemoryStream memStream = new MemoryStream();
binFormatter.Serialize(memStream, img);
byte[] bytes = memStream.GetBuffer();
string base64 = Convert.ToBase64String(bytes);
return base64;
}
/// <summary>
/// 将Base64字符串转换为图片
/// </summary>
public static Image ToImage(string base64)
{
if (base64 == null || base64 == "")
{
return null;
}
byte[] bytes = Convert.FromBase64String(base64);
MemoryStream memStream = new MemoryStream(bytes);
BinaryFormatter binFormatter = new BinaryFormatter();
Image img = (Image)binFormatter.Deserialize(memStream);
return img;
}
}
}

using OpenCvSharp;
using OpenCvSharp.Blob;
using OpenCvSharp.Extensions;
using OpenCvSharp.XFeatures2D;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace AOI
{
public class ImageUtil
{
public static Mat ToMat(Image image)
{
return BitmapConverter.ToMat(new Bitmap(image));
}
public static Image ToImage(Mat mat)
{
return BitmapConverter.ToBitmap(mat);
}
}
}
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace AOI
{
public class JsonUtil
{
/// <summary>
/// 将对象序列化为JSON格式
/// </summary>
/// <param name="o">对象</param>
/// <returns>json字符串</returns>
public static string SerializeObject(object o)
{
string json = JsonConvert.SerializeObject(o);
return json;
}
/// <summary>
/// 将对象序列化为JSON格式
/// </summary>
/// <param name="o">对象</param>
/// <returns>json字符串</returns>
public static bool SerializeObjectToFile(object o, string filePath, bool backUp)
{
try
{
string json = JsonConvert.SerializeObject(o);
if (File.Exists(filePath))
{
if (backUp)
{
//String Path = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
string backUpPath = filePath + "." + DateTime.Now.ToString("yyyyMMddHHmmssfff");
File.Copy(filePath, backUpPath);
}
File.Delete(filePath);
}
File.WriteAllText(filePath, json);
return true;
}
catch (Exception ex)
{
//LogUtil.error("保存文件到[" + filePath + "]失败:" + ex.Message);
}
return false;
}
/// <summary>
/// 解析JSON字符串生成对象实体
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json字符串(eg.{"ID":"112","Name":"石子儿"})</param>
/// <returns>对象实体</returns>
public static T DeserializeJsonToObject<T>(string json) where T : class
{
JsonSerializer serializer = new JsonSerializer();
StringReader sr = new StringReader(json);
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(T));
T t = o as T;
return t;
}
/// <summary>
/// 解析文件到生成对象实体
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json字符串(eg.{"ID":"112","Name":"石子儿"})</param>
/// <returns>对象实体</returns>
public static T DeserializeJsonToObjectFromFile<T>(string filePath) where T : class
{
if (!File.Exists(filePath))
{
//LogUtil.error("加载:文件[" + filePath + "]不存在");
return null;
}
string jsonTxt = File.ReadAllText(filePath);
JsonSerializer serializer = new JsonSerializer();
StringReader sr = new StringReader(jsonTxt);
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(T));
T t = o as T;
return t;
}
/// <summary>
/// 解析JSON数组生成对象实体集合
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json数组字符串(eg.[{"ID":"112","Name":"石子儿"}])</param>
/// <returns>对象实体集合</returns>
public static List<T> DeserializeJsonToList<T>(string json) where T : class
{
JsonSerializer serializer = new JsonSerializer();
StringReader sr = new StringReader(json);
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(List<T>));
List<T> list = o as List<T>;
return list;
}
/// <summary>
/// 解析文件
/// </summary>
/// <typeparam name="T">对象类型</typeparam>
/// <param name="json">json数组字符串(eg.[{"ID":"112","Name":"石子儿"}])</param>
/// <returns>对象实体集合</returns>
public static List<T> DeserializeJsonToListFromFile<T>(string filePath) where T : class
{
if (!File.Exists(filePath))
{
//LogUtil.error("加载:文件[" + filePath + "]不存在");
return new List<T>();
}
string jsonTxt = File.ReadAllText(filePath);
JsonSerializer serializer = new JsonSerializer();
StringReader sr = new StringReader(jsonTxt);
object o = serializer.Deserialize(new JsonTextReader(sr), typeof(List<T>));
List<T> list = o as List<T>;
return list;
}
/// <summary>
/// 反序列化JSON到给定的匿名对象.
/// </summary>
/// <typeparam name="T">匿名对象类型</typeparam>
/// <param name="json">json字符串</param>
/// <param name="anonymousTypeObject">匿名对象</param>
/// <returns>匿名对象</returns>
public static T DeserializeAnonymousType<T>(string json, T anonymousTypeObject)
{
T t = JsonConvert.DeserializeAnonymousType(json, anonymousTypeObject);
return t;
}
}
}

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27703.2035
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AccAOI", "AccAOI\AccAOI.csproj", "{81D116DC-69C9-4B3B-AB7B-E324AF18CA3E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageBox", "ImageBox\ImageBox.csproj", "{DB03ED04-5E06-4FEB-B891-0633448F24EC}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AOI", "AOI\AOI.csproj", "{529F3829-BD91-42A7-95AF-9DEA2DC409CB}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{81D116DC-69C9-4B3B-AB7B-E324AF18CA3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81D116DC-69C9-4B3B-AB7B-E324AF18CA3E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81D116DC-69C9-4B3B-AB7B-E324AF18CA3E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81D116DC-69C9-4B3B-AB7B-E324AF18CA3E}.Release|Any CPU.Build.0 = Release|Any CPU
{DB03ED04-5E06-4FEB-B891-0633448F24EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DB03ED04-5E06-4FEB-B891-0633448F24EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DB03ED04-5E06-4FEB-B891-0633448F24EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DB03ED04-5E06-4FEB-B891-0633448F24EC}.Release|Any CPU.Build.0 = Release|Any CPU
{529F3829-BD91-42A7-95AF-9DEA2DC409CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{529F3829-BD91-42A7-95AF-9DEA2DC409CB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{529F3829-BD91-42A7-95AF-9DEA2DC409CB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{529F3829-BD91-42A7-95AF-9DEA2DC409CB}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9483E9C2-E09B-497C-A69A-A8DFF75803C7}
EndGlobalSection
EndGlobal
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{81D116DC-69C9-4B3B-AB7B-E324AF18CA3E}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>AccAOI</RootNamespace>
<AssemblyName>AccAOI</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Deployment" />
<Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="imageBoxEx\DragHandle.cs" />
<Compile Include="imageBoxEx\DragHandleAnchor.cs" />
<Compile Include="imageBoxEx\DragHandleCollection.cs" />
<Compile Include="imageBoxEx\ImageBoxEx.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Compile Include="Properties\Settings.Designer.cs">
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\AOI\AOI.csproj">
<Project>{529f3829-bd91-42a7-95af-9dea2dc409cb}</Project>
<Name>AOI</Name>
</ProjectReference>
<ProjectReference Include="..\ImageBox\ImageBox.csproj">
<Project>{db03ed04-5e06-4feb-b891-0633448f24ec}</Project>
<Name>ImageBox</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file \ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
\ No newline at end of file \ No newline at end of file
using Cyotek.Windows.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AccAOI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private Image originalImage;
private void buttonOpen_Click(object sender, EventArgs e)
{
using (FileDialog dialog = new OpenFileDialog())
{
dialog.Filter = "All Supported Images (*.bmp;*.dib;*.rle;*.gif;*.jpg;*.png)|*.bmp;*.dib;*.rle;*.gif;*.jpg;*.png|Bitmaps (*.bmp;*.dib;*.rle)|*.bmp;*.dib;*.rle|Graphics Interchange Format (*.gif)|*.gif|Joint Photographic Experts (*.jpg)|*.jpg|Portable Network Graphics (*.png)|*.png|All Files (*.*)|*.*";
dialog.DefaultExt = "png";
if (dialog.ShowDialog(this) == DialogResult.OK)
{
try
{
originalImage = Image.FromFile(dialog.FileName);
imageBox.Image = originalImage;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, this.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
}
private void imageBox_Selected(object sender, EventArgs e)
{
//Image selectImage = imageBox.GetSelectedImage();
//RectangleF region = imageBox.SelectionRegion;
//Image threshImage = ImageUtil.Merge(originalImage, selectImage, region);
//imageBox.Image = threshImage;
}
private void imageBox_SelectionRegionChanged(object sender, EventArgs e)
{
//Image selectImage = imageBox.GetSelectedImage();
//if (selectImage != null)
//{
Matrix translateMatrix = new Matrix();
translateMatrix.Translate(100, 0);
RectangleF region = imageBox.SelectionRegion;
GraphicsPath path = new GraphicsPath();
path.AddEllipse(region);
Image threshImage = CutImage(imageBox.Image, path);
cutImage = threshImage;
imageBoxEx1.Image = threshImage;
}
private Image CutImage(Image src, GraphicsPath path)
{
var bounds = path.GetBounds();
Bitmap b = new Bitmap(src.Width, src.Height);
using (Graphics g = Graphics.FromImage(b))
{
var br = new TextureBrush(src);
g.FillPath(br, path);
}
if(bounds.Width > 0 && bounds.Height > 0)
{
Bitmap result = new Bitmap((int)bounds.Width, (int)bounds.Height);
var srcRect = bounds;
var dstRect = new RectangleF(0, 0, bounds.Width, bounds.Height);
bounds.Location = System.Drawing.Point.Empty;
using (Graphics g = Graphics.FromImage(result))
{
bounds.Location = System.Drawing.Point.Empty;
g.DrawImage(b, dstRect, srcRect, GraphicsUnit.Pixel);
}
return result;
}
return null;
}
Image cutImage;
private void InRangeImage()
{
//Mat src = BitmapConverter.ToMat(new Bitmap(cutImage));
//Cv2.CvtColor(src, src, ColorConversionCodes.BGRA2BGR);
//Mat dst = new Mat();
//Scalar minScalar = Scalar.FromRgb((int)minR.Value, (int)minG.Value, (int)minB.Value);
//Scalar maxScalar = Scalar.FromRgb((int)maxR.Value, (int)maxG.Value, (int)maxB.Value);
//Cv2.InRange(src, minScalar, maxScalar, dst);
//int count = Cv2.CountNonZero(dst);
//labelCount.Text = count + "";
//src.CopyTo(dst, dst);
//imageBoxEx1.Image = BitmapConverter.ToBitmap(dst);
}
private void minR_ValueChanged(object sender, EventArgs e)
{
InRangeImage();
}
private void maxR_ValueChanged(object sender, EventArgs e)
{
InRangeImage();
}
private void minG_ValueChanged(object sender, EventArgs e)
{
InRangeImage();
}
private void maxG_ValueChanged(object sender, EventArgs e)
{
InRangeImage();
}
private void minB_ValueChanged(object sender, EventArgs e)
{
InRangeImage();
}
private void maxB_ValueChanged(object sender, EventArgs e)
{
InRangeImage();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
\ No newline at end of file \ No newline at end of file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AccAOI
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("AccAOI")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("AccAOI")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("81d116dc-69c9-4b3b-ab7b-e324af18ca3e")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本: 4.0.30319.42000
//
// 对此文件的更改可能导致不正确的行为,如果
// 重新生成代码,则所做更改将丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace AccAOI.Properties
{
/// <summary>
/// 强类型资源类,用于查找本地化字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources
{
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources()
{
}
/// <summary>
/// 返回此类使用的缓存 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager
{
get
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("AccAOI.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 覆盖当前线程的 CurrentUICulture 属性
/// 使用此强类型的资源类的资源查找。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
{
get
{
return resourceCulture;
}
set
{
resourceCulture = value;
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
\ No newline at end of file \ No newline at end of file
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace AccAOI.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
{
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
public static Settings Default
{
get
{
return defaultInstance;
}
}
}
}
<?xml version='1.0' encoding='utf-8'?>
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
<Profiles>
<Profile Name="(Default)" />
</Profiles>
<Settings />
</SettingsFile>
using System.Drawing;
namespace AccAOI
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal class DragHandle
{
#region Public Constructors
public DragHandle(DragHandleAnchor anchor)
: this()
{
this.Anchor = anchor;
}
#endregion
#region Protected Constructors
protected DragHandle()
{
this.Enabled = true;
this.Visible = true;
}
#endregion
#region Public Properties
public DragHandleAnchor Anchor { get; protected set; }
public Rectangle Bounds { get; set; }
public bool Enabled { get; set; }
public bool Visible { get; set; }
#endregion
}
}
namespace AccAOI
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal enum DragHandleAnchor
{
None,
TopLeft,
TopCenter,
TopRight,
MiddleLeft,
MiddleCenter,
MiddleRight,
BottomLeft,
BottomCenter,
BottomRight
}
}
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
namespace AccAOI
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
internal class DragHandleCollection : IEnumerable<DragHandle>
{
#region Instance Fields
private readonly IDictionary<DragHandleAnchor, DragHandle> _items;
#endregion
#region Public Constructors
public DragHandleCollection()
{
_items = new Dictionary<DragHandleAnchor, DragHandle>();
_items.Add(DragHandleAnchor.TopLeft, new DragHandle(DragHandleAnchor.TopLeft));
_items.Add(DragHandleAnchor.TopCenter, new DragHandle(DragHandleAnchor.TopCenter));
_items.Add(DragHandleAnchor.TopRight, new DragHandle(DragHandleAnchor.TopRight));
_items.Add(DragHandleAnchor.MiddleLeft, new DragHandle(DragHandleAnchor.MiddleLeft));
_items.Add(DragHandleAnchor.MiddleRight, new DragHandle(DragHandleAnchor.MiddleRight));
_items.Add(DragHandleAnchor.BottomLeft, new DragHandle(DragHandleAnchor.BottomLeft));
_items.Add(DragHandleAnchor.BottomCenter, new DragHandle(DragHandleAnchor.BottomCenter));
_items.Add(DragHandleAnchor.BottomRight, new DragHandle(DragHandleAnchor.BottomRight));
_items.Add(DragHandleAnchor.MiddleCenter, new DragHandle(DragHandleAnchor.MiddleCenter));
}
#endregion
#region Public Properties
public int Count
{
get { return _items.Count; }
}
public DragHandle this[DragHandleAnchor index]
{
get { return _items[index]; }
}
#endregion
#region Public Members
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/> that can be used to iterate through the collection.
/// </returns>
public IEnumerator<DragHandle> GetEnumerator()
{
return _items.Values.GetEnumerator();
}
public DragHandleAnchor HitTest(Point point)
{
DragHandleAnchor result;
result = DragHandleAnchor.None;
foreach (DragHandle handle in this)
{
if (handle.Visible && handle.Bounds.Contains(point))
{
result = handle.Anchor;
break;
}
}
return result;
}
#endregion
#region IEnumerable<DragHandle> Members
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>
/// An <see cref="T:System.Collections.IEnumerator"/> object that can be used to iterate through the collection.
/// </returns>
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}
}
此文件类型无法预览
此文件的差异太大,无法显示。
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{DB03ED04-5E06-4FEB-B891-0633448F24EC}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ImageBox</RootNamespace>
<AssemblyName>ImageBox</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="ImageBox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ImageBox\ImageBoxActionSources.cs" />
<Compile Include="ImageBox\ImageBoxBorderStyle.cs" />
<Compile Include="ImageBox\ImageBoxCancelEventArgs.cs" />
<Compile Include="ImageBox\ImageBoxGridDisplayMode.cs" />
<Compile Include="ImageBox\ImageBoxGridScale.cs" />
<Compile Include="ImageBox\ImageBoxNativeMethods.cs" />
<Compile Include="ImageBox\ImageBoxSelectionMode.cs" />
<Compile Include="ImageBox\ImageBoxSizeMode.cs" />
<Compile Include="ImageBox\ImageBoxZoomActions.cs" />
<Compile Include="ImageBox\ImageBoxZoomEventArgs.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ImageBox\ScrollControl.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ImageBox\ScrollProperties.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ImageBox\VirtualScrollableControl.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="ImageBox\ZoomLevelCollection.cs" />
<Compile Include="ImageBox\ZoomLevelCollectionConverter.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="ImageBox.bmp" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file \ No newline at end of file
using System;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Specifies the source of an action being performed.
/// </summary>
[Flags]
public enum ImageBoxActionSources
{
/// <summary>
/// Unknown source.
/// </summary>
Unknown = 0,
/// <summary>
/// A user initialized the action.
/// </summary>
User = 1
}
}
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Specifies the border styles of an image
/// </summary>
public enum ImageBoxBorderStyle
{
/// <summary>
/// No border.
/// </summary>
None,
/// <summary>
/// A fixed, single-line border.
/// </summary>
FixedSingle,
/// <summary>
/// A fixed, single-line border with a solid drop shadow.
/// </summary>
FixedSingleDropShadow,
/// <summary>
/// A fixed, single-line border with a soft outer glow.
/// </summary>
FixedSingleGlowShadow
}
}
using System.ComponentModel;
using System.Drawing;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Provides data for a cancelable event.
/// </summary>
public class ImageBoxCancelEventArgs : CancelEventArgs
{
#region Public Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ImageBoxCancelEventArgs"/> class.
/// </summary>
/// <param name="location">The location of the action being performed.</param>
public ImageBoxCancelEventArgs(Point location)
: this()
{
this.Location = location;
}
#endregion
#region Protected Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ImageBoxCancelEventArgs"/> class.
/// </summary>
protected ImageBoxCancelEventArgs()
{ }
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the location of the action being performed.
/// </summary>
/// <value>The location of the action being performed.</value>
public Point Location { get; protected set; }
#endregion
}
}
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Specifies the display styles for the background texture grid
/// </summary>
public enum ImageBoxGridDisplayMode
{
/// <summary>
/// No background.
/// </summary>
None,
/// <summary>
/// Background is displayed in the control's client area.
/// </summary>
Client,
/// <summary>
/// Background is displayed only in the image region.
/// </summary>
Image
}
}
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Specifies the size of the background texture grid.
/// </summary>
public enum ImageBoxGridScale
{
/// <summary>
/// Displays a solid color
/// </summary>
None,
/// <summary>
/// Half of the default size.
/// </summary>
Tiny,
/// <summary>
/// Default size.
/// </summary>
Small,
/// <summary>
/// 50% increase of default size.
/// </summary>
Medium,
/// <summary>
/// 100% increase of default size.
/// </summary>
Large
}
}
using System;
using System.Runtime.InteropServices;
// ReSharper disable NotAccessedField.Global
// ReSharper disable InconsistentNaming
// ReSharper disable FieldCanBeMadeReadOnly.Global
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
// ReSharper disable ClassNeverInstantiated.Global
// ReSharper disable PartialTypeWithSinglePart
internal partial class NativeMethods // partial for when linking this file into other assemblies
// ReSharper restore PartialTypeWithSinglePart
// ReSharper restore ClassNeverInstantiated.Global
{
#region Enums
[Flags]
public enum SIF
{
SIF_RANGE = 0x0001,
SIF_PAGE = 0x0002,
SIF_POS = 0x0004,
SIF_DISABLENOSCROLL = 0x0008,
SIF_TRACKPOS = 0x0010,
SIF_ALL = SIF_PAGE | SIF_POS | SIF_RANGE | SIF_TRACKPOS
}
#endregion
#region Constants
public const int GWL_STYLE = (-16);
public const int SB_BOTH = 3;
public const int SB_BOTTOM = 7;
public const int SB_CTL = 2;
public const int SB_ENDSCROLL = 8;
public const int SB_HORZ = 0;
public const int SB_LEFT = 6;
public const int SB_LINEDOWN = 1;
public const int SB_LINELEFT = 0;
public const int SB_LINERIGHT = 1;
public const int SB_LINEUP = 0;
public const int SB_PAGEDOWN = 3;
public const int SB_PAGELEFT = 2;
public const int SB_PAGERIGHT = 3;
public const int SB_PAGEUP = 2;
public const int SB_RIGHT = 7;
public const int SB_THUMBPOSITION = 4;
public const int SB_THUMBTRACK = 5;
public const int SB_TOP = 6;
public const int SB_VERT = 1;
public const int WM_HSCROLL = 0x00000114;
public const int WM_VSCROLL = 0x00000115;
public const int WS_BORDER = 0x00800000;
public const int WS_EX_CLIENTEDGE = 0x200;
public const int WS_HSCROLL = 0x00100000;
public const int WS_VSCROLL = 0x00200000;
#endregion
#region Private Constructors
private NativeMethods()
{ }
#endregion
#region Class Members
[DllImport("user32.dll", SetLastError = true)]
public static extern int GetScrollInfo(IntPtr hwnd, int bar, [MarshalAs(UnmanagedType.LPStruct)] SCROLLINFO scrollInfo);
[DllImport("user32.dll", SetLastError = true)]
public static extern uint GetWindowLong(IntPtr hwnd, int index);
[DllImport("user32.dll")]
public static extern int SetScrollInfo(IntPtr hwnd, int bar, [MarshalAs(UnmanagedType.LPStruct)] SCROLLINFO scrollInfo, bool redraw);
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hwnd, int index, UInt32 newLong);
#endregion
#region Nested Types
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public class SCROLLINFO
{
public int cbSize;
public SIF fMask;
public int nMin;
public int nMax;
public int nPage;
public int nPos;
public int nTrackPos;
public SCROLLINFO()
{
cbSize = Marshal.SizeOf(this);
nPage = 0;
nMin = 0;
nMax = 0;
nPos = 0;
nTrackPos = 0;
fMask = 0;
}
}
#endregion
}
// ReSharper restore NotAccessedField.Global
// ReSharper restore FieldCanBeMadeReadOnly.Global
// ReSharper restore InconsistentNaming
}
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Specifies the selection mode.
/// </summary>
public enum ImageBoxSelectionMode
{
/// <summary>
/// No selection.
/// </summary>
None,
/// <summary>
/// Rectangle selection.
/// </summary>
Rectangle,
/// <summary>
/// Zoom selection.
/// </summary>
Zoom
}
}
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Determines the sizing mode of an image hosted in an <see cref="ImageBox" /> control.
/// </summary>
public enum ImageBoxSizeMode
{
/// <summary>
/// The image is disiplayed according to current zoom and scroll properties.
/// </summary>
Normal,
/// <summary>
/// The image is stretched to fill the client area of the control.
/// </summary>
Stretch,
/// <summary>
/// The image is stretched to fill as much of the client area of the control as possible, whilst retaining the same aspect ratio for the width and height.
/// </summary>
Fit
}
}
using System;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Describes the zoom action occuring
/// </summary>
[Flags]
public enum ImageBoxZoomActions
{
/// <summary>
/// No action.
/// </summary>
None = 0,
/// <summary>
/// The control is increasing the zoom.
/// </summary>
ZoomIn = 1,
/// <summary>
/// The control is decreasing the zoom.
/// </summary>
ZoomOut = 2,
/// <summary>
/// The control zoom was reset.
/// </summary>
ActualSize = 4
}
}
using System;
namespace Cyotek.Windows.Forms
{
// Cyotek ImageBox
// Copyright (c) 2010-2014 Cyotek.
// http://cyotek.com
// http://cyotek.com/blog/tag/imagebox
// Licensed under the MIT License. See imagebox-license.txt for the full text.
// If you use this control in your applications, attribution, donations or contributions are welcome.
/// <summary>
/// Contains event data for the <see cref="ImageBox.ZoomChanged"/> event.
/// </summary>
public class ImageBoxZoomEventArgs : EventArgs
{
#region Public Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ImageBoxZoomEventArgs"/> class.
/// </summary>
/// <param name="actions">The zoom operation being performed.</param>
/// <param name="source">The source of the operation.</param>
/// <param name="oldZoom">The old zoom level.</param>
/// <param name="newZoom">The new zoom level.</param>
public ImageBoxZoomEventArgs(ImageBoxZoomActions actions, ImageBoxActionSources source, int oldZoom, int newZoom)
: this()
{
this.Actions = actions;
this.Source = source;
this.OldZoom = oldZoom;
this.NewZoom = newZoom;
}
#endregion
#region Protected Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ImageBoxZoomEventArgs"/> class.
/// </summary>
protected ImageBoxZoomEventArgs()
{ }
#endregion
#region Public Properties
/// <summary>
/// Gets or sets the actions that occured.
/// </summary>
/// <value>The zoom operation.</value>
public ImageBoxZoomActions Actions { get; protected set; }
/// <summary>
/// Gets or sets the new zoom level.
/// </summary>
/// <value>The new zoom level.</value>
public int NewZoom { get; protected set; }
/// <summary>
/// Gets or sets the old zoom level.
/// </summary>
/// <value>The old zoom level.</value>
public int OldZoom { get; protected set; }
/// <summary>
/// Gets or sets the source of the operation..
/// </summary>
/// <value>The source.</value>
public ImageBoxActionSources Source { get; protected set; }
#endregion
}
}
using System.ComponentModel;
// Original ScrollControl code by Scott Crawford (http://sukiware.com/)
namespace Cyotek.Windows.Forms
{
partial class ScrollControl
{
#region Nested Types
/// <summary>
/// Provides basic properties for the horizontal scroll bar in a <see cref="ScrollControl"/>.
/// </summary>
public class HScrollProperties : ScrollProperties
{
#region Public Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ScrollProperties" /> class.
/// </summary>
/// <param name="container">The <see cref="ScrollControl" /> whose scrolling properties this object describes.</param>
public HScrollProperties(ScrollControl container)
: base(container)
{ }
#endregion
}
/// <summary>
/// Encapsulates properties related to scrolling.
/// </summary>
public abstract class ScrollProperties
{
#region Instance Fields
private readonly ScrollControl _container;
#endregion
#region Protected Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ScrollProperties"/> class.
/// </summary>
/// <param name="container">The <see cref="ScrollControl"/> whose scrolling properties this object describes.</param>
protected ScrollProperties(ScrollControl container)
{
//System.Windows.Forms.ScrollProperties
_container = container;
}
#endregion
#region Public Properties
/// <summary>
/// Gets or sets whether the scroll bar can be used on the container.
/// </summary>
/// <value><c>true</c> if the scroll bar can be used; otherwise, <c>false</c>.</value>
[DefaultValue(true)]
public bool Enabled { get; set; }
/// <summary>
/// Gets or sets the distance to move a scroll bar in response to a large scroll command.
/// </summary>
/// <value>An <see cref="int"/> describing how far, in pixels, to move the scroll bar in response to a large change.</value>
[DefaultValue(10)]
public int LargeChange { get; set; }
/// <summary>
/// Gets or sets the upper limit of the scrollable range.
/// </summary>
/// <value>An <see cref="int"/> representing the maximum range of the scroll bar.</value>
[DefaultValue(100)]
public int Maximum { get; set; }
/// <summary>
/// Gets or sets the lower limit of the scrollable range.
/// </summary>
/// <value>An <see cref="int"/> representing the lower range of the scroll bar.</value>
[DefaultValue(0)]
public int Minimum { get; set; }
/// <summary>
/// Gets the control to which this scroll information applies.
/// </summary>
/// <value>A <see cref="ScrollControl"/>.</value>
public ScrollControl ParentControl
{
get { return _container; }
}
/// <summary>
/// Gets or sets the distance to move a scroll bar in response to a small scroll command.
/// </summary>
/// <value>An <see cref="int"/> representing how far, in pixels, to move the scroll bar.</value>
[DefaultValue(1)]
public int SmallChange { get; set; }
/// <summary>
/// Gets or sets a numeric value that represents the current position of the scroll bar box.
/// </summary>
/// <value>An <see cref="int"/> representing the position of the scroll bar box, in pixels. </value>
[Bindable(true)]
[DefaultValue(0)]
public int Value { get; set; }
/// <summary>
/// Gets or sets whether the scroll bar can be seen by the user.
/// </summary>
/// <value><c>true</c> if it can be seen; otherwise, <c>false</c>.</value>
[DefaultValue(false)]
public bool Visible { get; set; }
#endregion
}
/// <summary>
/// Provides basic properties for the vertical scroll bar in a <see cref="ScrollControl"/>.
/// </summary>
public class VScrollProperties : ScrollProperties
{
#region Public Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ScrollProperties" /> class.
/// </summary>
/// <param name="container">The <see cref="ScrollControl" /> whose scrolling properties this object describes.</param>
public VScrollProperties(ScrollControl container)
: base(container)
{ }
#endregion
}
#endregion
}
}
using System;
using System.Collections;
using System.Collections.Generic;
namespace Cyotek.Windows.Forms
{
/// <summary>
/// Represents available levels of zoom in an <see cref="ImageBox"/> control
/// </summary>
public class ZoomLevelCollection : IList<int>
{
#region Public Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ZoomLevelCollection"/> class.
/// </summary>
public ZoomLevelCollection()
{
this.List = new SortedList<int, int>();
}
/// <summary>
/// Initializes a new instance of the <see cref="ZoomLevelCollection"/> class.
/// </summary>
/// <param name="collection">The default values to populate the collection with.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the <c>collection</c> parameter is null</exception>
public ZoomLevelCollection(IEnumerable<int> collection)
: this()
{
if (collection == null)
{
throw new ArgumentNullException("collection");
}
this.AddRange(collection);
}
#endregion
#region Class Properties
/// <summary>
/// Returns the default zoom levels
/// </summary>
public static ZoomLevelCollection Default
{
get
{
return new ZoomLevelCollection(new[]
{
7, 10, 15, 20, 25, 30, 50, 70, 100, 150, 200, 300, 400, 500, 600, 700, 800, 1200, 1600
});
}
}
#endregion
#region Public Properties
/// <summary>
/// Gets the number of elements contained in the <see cref="ZoomLevelCollection" />.
/// </summary>
/// <returns>
/// The number of elements contained in the <see cref="ZoomLevelCollection" />.
/// </returns>
public int Count
{
get { return this.List.Count; }
}
/// <summary>
/// Gets a value indicating whether the <see cref="T:System.Collections.Generic.ICollection`1" /> is read-only.
/// </summary>
/// <value><c>true</c> if this instance is read only; otherwise, <c>false</c>.</value>
/// <returns>true if the <see cref="T:System.Collections.Generic.ICollection`1" /> is read-only; otherwise, false.
/// </returns>
public bool IsReadOnly
{
get { return false; }
}
/// <summary>
/// Gets or sets the zoom level at the specified index.
/// </summary>
/// <param name="index">The index.</param>
public int this[int index]
{
get { return this.List.Values[index]; }
set
{
this.List.RemoveAt(index);
this.Add(value);
}
}
#endregion
#region Protected Properties
/// <summary>
/// Gets or sets the backing list.
/// </summary>
protected SortedList<int, int> List { get; set; }
#endregion
#region Public Members
/// <summary>
/// Adds an item to the <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </summary>
/// <param name="item">The object to add to the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
public void Add(int item)
{
this.List.Add(item, item);
}
/// <summary>
/// Adds a range of items to the <see cref="ZoomLevelCollection"/>.
/// </summary>
/// <param name="collection">The items to add to the collection.</param>
/// <exception cref="System.ArgumentNullException">Thrown if the <c>collection</c> parameter is null.</exception>
public void AddRange(IEnumerable<int> collection)
{
if (collection == null)
{
throw new ArgumentNullException("collection");
}
foreach (int value in collection)
{
this.Add(value);
}
}
/// <summary>
/// Removes all items from the <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </summary>
public void Clear()
{
this.List.Clear();
}
/// <summary>
/// Determines whether the <see cref="T:System.Collections.Generic.ICollection`1" /> contains a specific value.
/// </summary>
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
/// <returns>true if <paramref name="item" /> is found in the <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false.</returns>
public bool Contains(int item)
{
return this.List.ContainsKey(item);
}
/// <summary>
/// Copies a range of elements this collection into a destination <see cref="Array"/>.
/// </summary>
/// <param name="array">The <see cref="Array"/> that receives the data.</param>
/// <param name="arrayIndex">A 64-bit integer that represents the index in the <see cref="Array"/> at which storing begins.</param>
public void CopyTo(int[] array, int arrayIndex)
{
for (int i = 0; i < this.Count; i++)
{
array[arrayIndex + i] = this.List.Values[i];
}
}
/// <summary>
/// Finds the index of a zoom level matching or nearest to the specified value.
/// </summary>
/// <param name="zoomLevel">The zoom level.</param>
public int FindNearest(int zoomLevel)
{
int nearestValue = this.List.Values[0];
int nearestDifference = Math.Abs(nearestValue - zoomLevel);
for (int i = 1; i < this.Count; i++)
{
int value = this.List.Values[i];
int difference = Math.Abs(value - zoomLevel);
if (difference < nearestDifference)
{
nearestValue = value;
nearestDifference = difference;
}
}
return nearestValue;
}
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>A <see cref="T:System.Collections.Generic.IEnumerator`1" /> that can be used to iterate through the collection.</returns>
public IEnumerator<int> GetEnumerator()
{
return this.List.Values.GetEnumerator();
}
/// <summary>
/// Determines the index of a specific item in the <see cref="T:System.Collections.Generic.IList`1" />.
/// </summary>
/// <param name="item">The object to locate in the <see cref="T:System.Collections.Generic.IList`1" />.</param>
/// <returns>The index of <paramref name="item" /> if found in the list; otherwise, -1.</returns>
public int IndexOf(int item)
{
return this.List.IndexOfKey(item);
}
/// <summary>
/// Not implemented.
/// </summary>
/// <param name="index">The index.</param>
/// <param name="item">The item.</param>
/// <exception cref="System.NotImplementedException">Not implemented</exception>
public void Insert(int index, int item)
{
throw new NotImplementedException();
}
/// <summary>
/// Returns the next increased zoom level for the given current zoom.
/// </summary>
/// <param name="zoomLevel">The current zoom level.</param>
/// <returns>The next matching increased zoom level for the given current zoom if applicable, otherwise the nearest zoom.</returns>
public int NextZoom(int zoomLevel)
{
int index;
index = this.IndexOf(this.FindNearest(zoomLevel));
if (index < this.Count - 1)
{
index++;
}
return this[index];
}
/// <summary>
/// Returns the next decreased zoom level for the given current zoom.
/// </summary>
/// <param name="zoomLevel">The current zoom level.</param>
/// <returns>The next matching decreased zoom level for the given current zoom if applicable, otherwise the nearest zoom.</returns>
public int PreviousZoom(int zoomLevel)
{
int index;
index = this.IndexOf(this.FindNearest(zoomLevel));
if (index > 0)
{
index--;
}
return this[index];
}
/// <summary>
/// Removes the first occurrence of a specific object from the <see cref="T:System.Collections.Generic.ICollection`1" />.
/// </summary>
/// <param name="item">The object to remove from the <see cref="T:System.Collections.Generic.ICollection`1" />.</param>
/// <returns>true if <paramref name="item" /> was successfully removed from the <see cref="T:System.Collections.Generic.ICollection`1" />; otherwise, false. This method also returns false if <paramref name="item" /> is not found in the original <see cref="T:System.Collections.Generic.ICollection`1" />.</returns>
public bool Remove(int item)
{
return this.List.Remove(item);
}
/// <summary>
/// Removes the element at the specified index of the <see cref="ZoomLevelCollection"/>.
/// </summary>
/// <param name="index">The zero-based index of the element to remove.</param>
public void RemoveAt(int index)
{
this.List.RemoveAt(index);
}
/// <summary>
/// Copies the elements of the <see cref="ZoomLevelCollection"/> to a new array.
/// </summary>
/// <returns>An array containing copies of the elements of the <see cref="ZoomLevelCollection"/>.</returns>
public int[] ToArray()
{
int[] results;
results = new int[this.Count];
this.CopyTo(results, 0);
return results;
}
#endregion
#region IList<int> Members
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>An <see cref="ZoomLevelCollection" /> object that can be used to iterate through the collection.</returns>
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
namespace Cyotek.Windows.Forms
{
public class ZoomLevelCollectionConverter
: TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(InstanceDescriptor) || base.CanConvertTo(context, destinationType);
}
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
string data;
ZoomLevelCollection result;
data = value as string;
if (!string.IsNullOrEmpty(data))
{
char separator;
string[] items;
TypeConverter converter;
if (culture == null)
culture = CultureInfo.CurrentCulture;
result = new ZoomLevelCollection();
separator = culture.TextInfo.ListSeparator[0];
items = data.Split(separator);
converter = TypeDescriptor.GetConverter(typeof(int));
foreach (string item in items)
result.Add((int)converter.ConvertFromString(context, culture, item));
}
else
result = null;
return result;
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
object result;
if (destinationType == null)
throw new ArgumentNullException("destinationType");
if (value is ZoomLevelCollection)
{
if (destinationType == typeof(string))
{
ZoomLevelCollection collection;
StringBuilder data;
string separator;
TypeConverter converter;
collection = (ZoomLevelCollection)value;
if (culture == null)
culture = CultureInfo.CurrentCulture;
separator = culture.TextInfo.ListSeparator + " ";
converter = TypeDescriptor.GetConverter(typeof(int));
data = new StringBuilder();
foreach (int item in collection)
{
if (data.Length != 0)
data.Append(separator);
data.Append(converter.ConvertToString(context, culture, item));
}
result = data.ToString();
}
else if (destinationType == typeof(InstanceDescriptor))
{
ZoomLevelCollection collection;
ConstructorInfo constructor;
collection = (ZoomLevelCollection)value;
constructor = typeof(ZoomLevelCollection).GetConstructor(new Type[] { typeof(IList<int>) });
result = new InstanceDescriptor(constructor, new object[] { collection.ToArray() });
}
else
result = null;
}
else
result = null;
if (result == null)
result = base.ConvertTo(context, culture, value, destinationType);
return result;
}
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("ImageBox")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ImageBox")]
[assembly: AssemblyCopyright("Copyright © 2018")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("db03ed04-5e06-4feb-b891-0633448f24ec")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
//通过使用 "*",如下所示:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!