2026-01-26 18:56:53 +09:00

1590 lines
64 KiB
C#

/*
* Copyright (c) 2025 LG Electronics Inc.
* SPDX-License-Identifier: LicenseRef-LGE-Proprietary
*/
using Aurora;
using Aurora.Api;
using Aurora.Api.DataType;
using VisionCommon;
using Hermes;
using Matrox.MatroxImagingLibrary;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Linq;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Reactive.Linq;
using VisionCommonUI;
using VisionCommonUI.Resources;
namespace MilCommon {
/// <summary>
/// MIL 환경 변수 및 메소드 관리
/// </summary>
public class MilEnvironment : IDisposable {
private static readonly Logger _Logger = new Logger("MilEnvironment");
private static object LockObj = new object();
private MIL_INT _LicenseModules = 0;
private List<MIL_ID> DisplayList;
public MIL_ID Application { get; private set; }
// M_DEFAULT를 사용하는 경우, 시스템을 _DefaultSys 1개만 할당한다.
private MIL_ID _DefaultSys;
// M_DEFAULT가 아닐 경우, 시스템을 BoardType & Slot의 개수만큼 할당한다.
private Dictionary<eBoardType, Dictionary<eBoardSlotPos, MIL_ID>> Systems { get; set; }
= new Dictionary<eBoardType, Dictionary<eBoardSlotPos, MIL_ID>>();
private static MilEnvironment _instance = null;
/// <summary>
/// 싱글톤 객체
/// </summary>
public static MilEnvironment Instance {
get {
lock (LockObj) {
if (_instance == null) {
_instance = new MilEnvironment();
}
return _instance;
}
}
}
private MilEnvironment() {
IpAdapter.Instance.IpEnvironment = new IpEnvironment();
DisplayList = new List<MIL_ID>();
CheckLangToken();
AllocApp();
SetMilErrPrintType();
VisionEnv.AuroraEnv.EventObservable.AsObservable(AuroraSysEvent.SYS_SETTING_CHANGED)
.Where(msg => (string)msg.Param == VisionKeys.VisionSettingKey).Subscribe(x => UpdateVisionSettingActions());
}
private void CheckLangToken() {
string lastLanguage = (VisionEnv.AuroraEnv.SettingEntry[AuroraSettings.Equipment] as EquipmentInfo)?.Language ?? null;
if (lastLanguage != null && lastLanguage.Length > 0) {
System.Globalization.CultureInfo.CurrentCulture = new System.Globalization.CultureInfo(lastLanguage);
StrTokens.Culture = System.Globalization.CultureInfo.CurrentCulture;
}
}
private void AllocApp() {
try {
MIL_ID app = MIL.M_NULL;
MIL.MappAlloc(MIL.M_NULL, MIL.M_DEFAULT, ref app);
_Logger.FuncI(string.Format("MilApplication : {0}", app));
MIL.MappInquire(app, MIL.M_LICENSE_MODULES, ref _LicenseModules);
CheckMilVersion();
Application = app;
}
catch (Exception e) {
_Logger.E(e.Message);
}
}
private void CheckMilVersion() {
if (!VersionChecker.CheckMilVersionAndType()) {
MessageBoxUtil.ShowMessageBoxWarning(
string.Format(StrTokens.MSG_W_MilVersion, VersionChecker.GetMilVersion(), VersionChecker.GetMilType()));
}
}
private void UpdateVisionSettingActions() {
SetMilErrPrintType();
}
private void SetMilErrPrintType() {
var visionSetting = VisionEnv.AuroraEnv.SettingEntry[VisionKeys.VisionSettingKey] as VisionSetting;
switch (visionSetting.MilErrPrint) {
case eMilErrPrint.PRINT_ENABLE:
MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_ENABLE);
break;
case eMilErrPrint.PRINT_DISABLE:
MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_PRINT_DISABLE);
break;
case eMilErrPrint.THROW_EXCEPTION:
MIL.MappControl(MIL.M_DEFAULT, MIL.M_ERROR, MIL.M_THROW_EXCEPTION);
break;
}
}
/// <summary>
/// MIL 시스템 가져오기
/// </summary>
/// <param name="boardType">보드 타입</param>
/// <param name="boardSlotPos">보드 슬롯 위치</param>
/// <returns>MIL 시스템</returns>
public MIL_ID GetSystem(eBoardType boardType, eBoardSlotPos boardSlotPos) {
AllocSys(boardType, boardSlotPos);
if (Systems.ContainsKey(boardType)) {
if (Systems[boardType].ContainsKey(boardSlotPos)) {
return Systems[boardType][boardSlotPos];
}
else {
_Logger.FuncE($"MilSystems[{boardType}] do not contain boardSlotPos [{boardSlotPos}]");
}
}
else {
_Logger.FuncE($"MilSystems do not contain boardType [{boardType}]");
}
return MIL.M_NULL;
}
/// <summary>
/// MIL 시스템 할당 여부 체크
/// </summary>
/// <param name="boardType">보드 타입</param>
/// <param name="boardSlotPos">보드 슬롯 위치</param>
/// <returns></returns>
public bool IsSysAllocated(eBoardType boardType, eBoardSlotPos boardSlotPos) {
if (Systems.ContainsKey(boardType)) {
if (Systems[boardType].ContainsKey(boardSlotPos)) {
return true;
}
}
return false;
}
/// <summary>
/// 이미지로 MIL 시스템 가져오기
/// </summary>
/// <param name="image">이미지</param>
/// <returns>MIL 시스템</returns>
public static MIL_ID GetSystemOfBuffer(MIL_ID image) {
return (MIL_ID)MIL.MbufInquire(image, MIL.M_OWNER_SYSTEM, MIL.M_NULL);
}
/// <summary>
/// MIL 시스템 할당
/// </summary>
/// <param name="boardType">보드 타입</param>
/// <param name="boardSlotPos">보드 슬롯 위치</param>
public void AllocSys(eBoardType boardType, eBoardSlotPos boardSlotPos) {
try {
lock (LockObj) {
if (IsSysAllocated(boardType, boardSlotPos)) {
return;
}
if (!Systems.ContainsKey(boardType)) {
Systems.Add(boardType, new Dictionary<eBoardSlotPos, MIL_ID>());
}
if (!Systems[boardType].ContainsKey(boardSlotPos)) {
MIL_ID sys = MIL.M_NULL;
string sysDescriptor = GetSystemDescriptor(boardType);
if (sysDescriptor == MIL.M_SYSTEM_DEFAULT) {
// M_SYSTEM_DEFAULT일 경우 MIL System이 1개만 있으면 된다.
if (_DefaultSys == MIL.M_NULL) {
MIL.MsysAlloc(MIL.M_DEFAULT, sysDescriptor, (int)boardSlotPos, MIL.M_DEFAULT, ref _DefaultSys);
}
sys = _DefaultSys;
}
else {
// M_SYSTEM_DEFAULT이 아닐 경우 MIL System은 Slot 개수만큼 존재한다.
MIL.MsysAlloc(MIL.M_DEFAULT, sysDescriptor, (int)boardSlotPos, MIL.M_DEFAULT, ref sys);
}
_Logger.FuncI(string.Format("BoardType : {0} / BoardSlotPos : {1} / MilSystem[{2}] : {3}",
sysDescriptor, (int)boardSlotPos, (int)boardSlotPos, sys));
Systems[boardType].Add(boardSlotPos, sys);
}
}
}
catch (Exception e) {
_Logger.E(e.Message);
}
}
private string GetSystemDescriptor(eBoardType boardType) {
if (EquipmentInfoManager.EquipmentInfo.SimulationMode) {
// M_SYSTEM_DEFAULT일 경우, 시뮬에서 eBoardSlotPos이 달라도 eBoardType이 같으면 할당이 안됨.
return MIL.M_SYSTEM_HOST;
}
switch (boardType) {
case eBoardType.MIL_GIGE:
return MIL.M_SYSTEM_GIGE_VISION;
case eBoardType.MIL_CL_SOLIOS:
return MIL.M_SYSTEM_SOLIOS;
case eBoardType.MIL_CXP_RADIENT:
return MIL.M_SYSTEM_RADIENTCXP;
case eBoardType.MIL_CXP_RAPIXO:
return MIL.M_SYSTEM_RAPIXOCXP;
case eBoardType.EURESYS_GIGELINK:
case eBoardType.EURESYS_COAXLINK:
case eBoardType.EURESYS_GRABLINK:
default:
return MIL.M_SYSTEM_DEFAULT;
}
}
public static bool IsValidContextId(MIL_ID contextId) {
if (contextId != MIL.M_NULL) {
return true;
}
else {
return false;
}
}
/// <summary>
/// MIL 라이센스 체크
/// </summary>
/// <returns>라이센스 여부</returns>
public bool HasValidLicense() {
return (_LicenseModules & MIL.M_LICENSE_MOD) != 0;
}
/// <summary>
/// 디스플레이 생성
/// </summary>
/// <param name="WinFormHandle">윈폼 핸들러(IntPtr)</param>
/// <param name="imageBuffer">이미지 버퍼 Mil_ID</param>
/// <returns>Display ID (MIL_ID)</returns>
public MIL_ID CreateDisplay(IntPtr WinFormHandle, MIL_ID imageBuffer) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
lock (LockObj) {
MIL_ID displayId = MIL.M_NULL;
MIL.MdispAlloc(GetSystemOfBuffer(imageBuffer), MIL.M_DEFAULT, "MIL.M_DEFAULT", MIL.M_DEFAULT, ref displayId);
MIL.MdispSelectWindow(displayId, imageBuffer, WinFormHandle);
DisplayList.Add(displayId);
return displayId;
}
}
/// <summary>
/// 해당 디스플레이 선택
/// </summary>
/// <param name="WinFormHandle">윈폼 핸들러(IntPtr)</param>
/// <param name="imageBuffer">이미지 버퍼 Mil_ID</param>
/// <param name="displayId">선택할 Display Id (MIL_ID)</param>
public void SelectDisplay(IntPtr WinFormHandle, MIL_ID imageBuffer, MIL_ID displayId) {
if (!Instance.HasValidLicense()) {
return;
}
lock (LockObj) {
MIL.MdispSelectWindow(displayId, imageBuffer, WinFormHandle);
}
}
/// <summary>
/// 디스플레이 해제/제거
/// </summary>
/// <param name="displayId">해제할 Display Id (MIL_ID)</param>
public void DestroyDisplay(MIL_ID displayId) {
if (!Instance.HasValidLicense()) {
return;
}
lock (LockObj) {
if (displayId != MIL.M_NULL) {
DisplayList.Remove(displayId);
MIL.MdispFree(displayId);
}
}
}
[Obsolete]
public void Dispose() {
if (!Instance.HasValidLicense()) {
return;
}
foreach (var itemPairs in Systems) {
foreach (var systemPairs in itemPairs.Value) {
MIL_ID sys = systemPairs.Value;
if (sys != MIL.M_NULL) {
MIL.MsysFree(sys);
}
}
}
Systems.Clear();
if (Application != MIL.M_NULL) {
MIL.MappFree(Application);
}
}
/// <summary>
/// 원본 이미지 버퍼 할당
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <param name="image">원본 이미지 버퍼</param>
/// <returns>성공 유무</returns>
public int AllocOriginalImage(CamConfig camConfig, ref MIL_ID image) {
switch (camConfig.ImageSize.Channel) {
case 1:
// 원본이미지는 항상 정사이즈 (W > H)
MIL.MbufAlloc2d(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
camConfig.ImageSize.Width,
camConfig.ImageSize.Height,
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref image);
ClearImage((MIL_ID)image);
return (image == MIL.M_NULL || image == 0) ? E1.GENERIC : E1.OK;
case 3:
default:
// 원본이미지는 항상 정사이즈 (W > H)
MIL.MbufAllocColor(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
camConfig.ImageSize.Channel,
camConfig.ImageSize.Width,
camConfig.ImageSize.Height,
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref image);
ClearImage((MIL_ID)image);
return (image == MIL.M_NULL || image == 0) ? E1.GENERIC : E1.OK;
}
}
/// <summary>
/// Flip & Rotation 이미지 버퍼 할당
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <param name="image">Flip & Rotation 이미지 버퍼</param>
/// <returns>성공 유무</returns>
public int AllocFilteredImage(CamConfig camConfig, ref MIL_ID image) {
switch (camConfig.ImageSize.Channel) {
case 1:
if (IsHeightLongerThanWidth(camConfig)) {
// 가로 < 세로
MIL.MbufAlloc2d(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
camConfig.ImageSize.Height,
camConfig.ImageSize.Width,
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref image);
ClearImage((MIL_ID)image);
return (image == MIL.M_NULL || image == 0) ? E1.GENERIC : E1.OK;
}
else {
// 가로 > 세로
MIL.MbufAlloc2d(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
camConfig.ImageSize.Width,
camConfig.ImageSize.Height,
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref image);
ClearImage((MIL_ID)image);
return (image == MIL.M_NULL || image == 0) ? E1.GENERIC : E1.OK;
}
case 3:
default:
if (IsHeightLongerThanWidth(camConfig)) {
// 가로 < 세로
MIL.MbufAllocColor(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
camConfig.ImageSize.Channel,
camConfig.ImageSize.Height,
camConfig.ImageSize.Width,
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref image);
ClearImage((MIL_ID)image);
return (image == MIL.M_NULL || image == 0) ? E1.GENERIC : E1.OK;
}
else {
// 가로 > 세로
MIL.MbufAllocColor(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
camConfig.ImageSize.Channel,
camConfig.ImageSize.Width,
camConfig.ImageSize.Height,
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref image);
ClearImage((MIL_ID)image);
return (image == MIL.M_NULL || image == 0) ? E1.GENERIC : E1.OK;
}
}
}
/// <summary>
/// Crop 이미지 버퍼 할당
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <param name="image">Crop 이미지 버퍼</param>
/// <returns>성공 유무</returns>
public int AllocCroppedImage(CamConfig camConfig, ref MIL_ID image) {
switch (camConfig.ImageSize.Channel) {
case 1:
if (IsHeightLongerThanWidth(camConfig)) {
// 가로 < 세로
MIL.MbufAlloc2d(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
(int)(camConfig.ImageSize.Height * camConfig.ImageSizeRatioY),
(int)(camConfig.ImageSize.Width * camConfig.ImageSizeRatioX),
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref image);
ClearImage((MIL_ID)image);
return (image == MIL.M_NULL || image == 0) ? E1.GENERIC : E1.OK;
}
else {
// 가로 > 세로
MIL.MbufAlloc2d(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
(int)(camConfig.ImageSize.Width * camConfig.ImageSizeRatioX),
(int)(camConfig.ImageSize.Height * camConfig.ImageSizeRatioY),
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref image);
ClearImage((MIL_ID)image);
return (image == MIL.M_NULL || image == 0) ? E1.GENERIC : E1.OK;
}
case 3:
default:
if (IsHeightLongerThanWidth(camConfig)) {
// 가로 < 세로
MIL.MbufAllocColor(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
camConfig.ImageSize.Channel,
(int)(camConfig.ImageSize.Height * camConfig.ImageSizeRatioY),
(int)(camConfig.ImageSize.Width * camConfig.ImageSizeRatioX),
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref image);
ClearImage((MIL_ID)image);
return (image == MIL.M_NULL || image == 0) ? E1.GENERIC : E1.OK;
}
else {
// 가로 > 세로
MIL.MbufAllocColor(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
camConfig.ImageSize.Channel,
(int)(camConfig.ImageSize.Width * camConfig.ImageSizeRatioX),
(int)(camConfig.ImageSize.Height * camConfig.ImageSizeRatioY),
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref image);
ClearImage((MIL_ID)image);
return (image == MIL.M_NULL || image == 0) ? E1.GENERIC : E1.OK;
}
}
}
/// <summary>
/// Dig Process 이미지 배열 할당
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <param name="bufferSize">버퍼 사이즈</param>
/// <param name="images">Proc 이미지 버퍼 배열</param>
/// <returns></returns>
public int AllocProcImages(CamConfig camConfig, int bufferSize, ref object[] images) {
switch (camConfig.ImageSize.Channel) {
case 1:
for (int i = 0; i < bufferSize; i++) {
MIL_ID allocImage = MIL.M_NULL;
MIL.MbufAlloc2d(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
camConfig.ImageSize.Width,
camConfig.ImageSize.Height,
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref allocImage);
ClearImage(allocImage);
images[i] = allocImage;
}
break;
case 3:
default:
for (int i = 0; i < bufferSize; i++) {
MIL_ID allocImage = MIL.M_NULL;
MIL.MbufAllocColor(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
camConfig.ImageSize.Channel,
camConfig.ImageSize.Width,
camConfig.ImageSize.Height,
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref allocImage);
ClearImage(allocImage);
images[i] = allocImage;
}
break;
}
return E1.OK;
}
/// <summary>
/// Child 이미지 할당
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <param name="parentImage">부모 이미지 버퍼</param>
/// <param name="childImages">자식 이미지 버퍼 배열</param>
/// <returns></returns>
public int AllocChildImages(CamConfig camConfig, object parentImage, ref object[] childImages) {
try {
if (parentImage == null) {
_Logger.FuncE($"parentImage is null.");
return E1.GENERIC;
}
if (camConfig.ChildImage.ChildBufRowCols.Count == 0) {
// Default 설정
for (int rowIdx = 0; rowIdx < camConfig.ChildImage.RowCnt; rowIdx++) {
for (int colIdx = 0; colIdx < camConfig.ChildImage.ColCnt; colIdx++) {
camConfig.ChildImage.ChildBufRowCols.Add(new ChildBufRowCol() { RowIdx = rowIdx, ColIdx = colIdx});
}
}
}
childImages = new object[camConfig.ChildImage.ChildBufRowCols.Count];
for (int i = 0; i < childImages.Length; i++) {
childImages[i] = MIL.M_NULL;
}
int childWidth = camConfig.ImageSize.Width;
int childHeight = camConfig.ImageSize.Height;
for (int i = 0; i < camConfig.ChildImage.ChildBufRowCols.Count; i++) {
var childBufRowCol = camConfig.ChildImage.ChildBufRowCols[i];
//if (!childBufRowCol.Enabled) {
// continue;
//}
int offsetX = childBufRowCol.ColIdx * childWidth;
int offsetY = childBufRowCol.RowIdx * childHeight;
MIL_ID childImage = MIL.M_NULL;
MIL.MbufChild2d((MIL_ID)parentImage, offsetX, offsetY, childWidth, childHeight, ref childImage);
if (childImages.Length > childBufRowCol.PosIdx) {
childImages[childBufRowCol.PosIdx] = childImage;
}
else {
_Logger.FuncE("[ERROR] childImages.Length <= childBufRowCol.PosIdx");
}
}
}
catch (Exception e) {
_Logger.FuncE(e.Message);
return E1.GENERIC;
}
return E1.OK;
}
/// <summary>
/// Child 이미지 사용시, 부모 이미지 버퍼 할당
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <param name="image">부모 이미지 버퍼</param>
/// <returns>성공 유무</returns>
public int AllocParentImage(CamConfig camConfig, ref object image) {
MIL_ID allocImage = MIL.M_NULL;
switch (camConfig.ImageSize.Channel) {
case 1:
MIL.MbufAlloc2d(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
camConfig.ImageSize.Width * camConfig.ChildImage.ColCnt,
camConfig.ImageSize.Height * camConfig.ChildImage.RowCnt,
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref allocImage);
break;
case 3:
default:
MIL.MbufAllocColor(
GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos),
camConfig.ImageSize.Channel,
camConfig.ImageSize.Width * camConfig.ChildImage.ColCnt,
camConfig.ImageSize.Height * camConfig.ChildImage.RowCnt,
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref allocImage);
break;
}
ClearImage(allocImage);
image = allocImage;
return image == null ? E1.GENERIC : E1.OK;
}
/// <summary>
/// 이미지 반전 유무 확인
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <returns>이미지 반전 유무</returns>
public bool IsFlipEnabled(CamConfig camConfig) {
if (camConfig.FlipAndRotation.ImageFlip.Equals(eImageFlip.None))
return false;
else
return true;
}
/// <summary>
/// 이미지 회전 유무 확인
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <returns>이미지 회전 유무</returns>
public bool IsRotationEnabled(CamConfig camConfig) {
if (camConfig.FlipAndRotation.ImageRotation.Equals(eImageRotation.None) &&
camConfig.FlipAndRotation.ImageRotationOffset == 0)
return false;
else
return true;
}
/// <summary>
/// 이미지 세로 사이즈가 가로 사이즈보다 큰지 확인
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <returns>이미지 세로 사이즈가 가로 사이즈보다 크면 True</returns>
public bool IsHeightLongerThanWidth(CamConfig camConfig) {
switch (camConfig.FlipAndRotation.ImageRotation) {
case eImageRotation.CW_DEG_90:
case eImageRotation.CW_DEG_270:
return true;
}
return false;
}
/// <summary>
/// 이미지 저장
/// </summary>
/// <param name="filePath">파일경로</param>
/// <param name="imageId">이미지버퍼 MIL_ID</param>
/// <param name="roi">크롭(저장) 할 영역</param>
/// <returns>성공 유무</returns>
public static int SaveImage(string filePath, MIL_ID imageId, Rect roi) {
if (!Instance.HasValidLicense()) {
return E1.GENERIC;
}
try {
MIL_ID childImage = CropImage(imageId, roi);
SaveImage(filePath, childImage);
}
catch (Exception e) {
_Logger.FuncE(e.Message);
return E1.GENERIC;
}
return E1.OK;
}
/// <summary>
/// 이미지 저장
/// </summary>
/// <param name="filePath">파일경로</param>
/// <param name="imageId">이미지버퍼 MIL_ID</param>
/// <returns>성공 유무</returns>
public static int SaveImage(string filePath, MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return E1.GENERIC;
}
try {
var dirPath = Path.GetDirectoryName(filePath);
if (!Directory.Exists(dirPath)) {
new DirectoryInfo(dirPath).Create();
}
if (filePath.ToLower().EndsWith("bmp")) {
MIL.MbufExport(filePath, MIL.M_BMP, imageId);
}
else if (filePath.ToLower().EndsWith("png")) {
MIL.MbufExport(filePath, MIL.M_PNG, imageId);
}
else if (filePath.ToLower().EndsWith("jpg")) {
MIL.MbufExport(filePath, MIL.M_JPEG_LOSSY, imageId);
}
else {
MIL.MbufExport(filePath, MIL.M_PNG, imageId);
}
}
catch (Exception e) {
_Logger.FuncE(e.Message);
return E1.GENERIC;
}
return E1.OK;
}
/// <summary>
/// 이미지 로드
/// </summary>
/// <param name="filePath">불러올 이미지 경로</param>
/// <param name="boardType">보드 타입</param>
/// <param name="boardSlotPos">보드 슬롯 위치</param>
/// <returns>이미지 버퍼 MIL_ID</returns>
public static MIL_ID LoadImage(string filePath, CamConfig camConfig) {
return LoadImage(filePath, Instance.GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos));
}
/// <summary>
/// 이미지 로드
/// </summary>
/// <param name="filePath">불러올 이미지 경로</param>
/// <param name="milSystemId">Mil 시스템 Id</param>
/// <returns>이미지 버퍼 MIL_ID</returns>
public static MIL_ID LoadImage(string filePath, MIL_ID milSystemId) {
MIL_ID loadImage = MIL.M_NULL;
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
try {
if (!File.Exists(filePath)) {
return E1.GENERIC;
}
MIL.MbufRestore(filePath, milSystemId, ref loadImage);
}
catch (Exception e) {
_Logger.FuncE(e.Message);
return E1.GENERIC;
}
return loadImage;
}
/// <summary>
/// 이미지 복사
/// </summary>
/// <param name="srcImage">소스 이미지 버퍼</param>
/// <param name="dstImage">목적지 이미지 버퍼</param>
/// <returns>성공 유무</returns>
public static int CopyImage(MIL_ID srcImage, MIL_ID dstImage) {
if (!Instance.HasValidLicense()) {
return E1.GENERIC;
}
if (IsCopyableBuffer(srcImage, dstImage)) {
MIL.MbufCopy(srcImage, dstImage);
return E1.OK;
}
return E1.GENERIC;
}
/// <summary>
/// 버퍼 카피 가능한지 여부
/// </summary>
/// <param name="srcImage">소스 이미지 버퍼</param>
/// <param name="dstImage">목적지 이미지 버퍼</param>
/// <returns></returns>
public static bool IsCopyableBuffer(MIL_ID srcImage, MIL_ID dstImage) {
if (!Instance.HasValidLicense()) {
return false;
}
var srcImageSize = GetImageSize(srcImage);
var dstImageSize = GetImageSize(dstImage);
if (srcImageSize.Width == dstImageSize.Width &&
srcImageSize.Height == dstImageSize.Height) {
return true;
}
return false;
}
/// <summary>
/// 이미지 복제
/// </summary>
/// <param name="imageId">복제할 이미지 ID</param>
/// <returns>복제된 이미지 MIL_ID</returns>
public static MIL_ID CloneImage(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
return CloneImage(imageId, GetSystemOfBuffer(imageId));
}
/// <summary>
/// 이미지 복제
/// </summary>
/// <param name="imageId">복제할 이미지 ID</param>
/// <param name="systemId">MIL 시스템 ID</param>
/// <returns>복제된 이미지 MIL_ID</returns>
public static MIL_ID CloneImage(MIL_ID imageId, MIL_ID systemId) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
return MIL.MbufClone(imageId, systemId,
MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_IMAGE + MIL.M_PROC + MIL.M_DISP, MIL.M_COPY_SOURCE_DATA, MIL.M_NULL);
}
/// <summary>
/// 호환가능한 이미지 버퍼 가져오기
/// </summary>
/// <param name="imageId">이미지 버퍼 MIL_ID</param>
/// <returns>호환가능한 이미지 버퍼 MIL_ID</returns>
public static MIL_ID GetCompatibleImageBuffer(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
var imageSize = GetImageSize(imageId);
return GetCompatibleImageBuffer(imageSize, GetSystemOfBuffer(imageId));
}
/// <summary>
/// 호환가능한 이미지 버퍼 가져오기
/// </summary>
/// <param name="imageSize">이미지 사이즈</param>
/// <param name="boardType">보드 타입</param>
/// <param name="boardSlotPos">보드 슬롯 위치</param>
/// <returns>호환가능한 이미지 버퍼 MIL_ID</returns>
public static MIL_ID GetCompatibleImageBuffer(ImageSize imageSize, eBoardType boardType, eBoardSlotPos boardSlotPos) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
return GetCompatibleImageBuffer(imageSize, Instance.GetSystem(boardType, boardSlotPos));
}
/// <summary>
/// 호환가능한 이미지 버퍼 가져오기
/// </summary>
/// <param name="imageSize">이미지 사이즈</param>
/// <param name="systemId"> Mil 시스템 Id</param>
/// <returns>호환가능한 이미지 버퍼 MIL_ID</returns>
public static MIL_ID GetCompatibleImageBuffer(ImageSize imageSize, MIL_ID systemId) {
if (imageSize.Channel == 1) {
return GetCompatibleGrayImageBuffer(imageSize, systemId);
}
else {
return GetCompatibleColorImageBuffer(imageSize, systemId);
}
}
/// <summary>
/// 호환가능한 Gray 이미지 버퍼 가져오기
/// </summary>
/// <param name="imageId">이미지 버퍼 MIL_ID</param>
/// <returns>호환가능한 Gray 이미지 버퍼 MIL_ID</returns>
public static MIL_ID GetCompatibleGrayImageBuffer(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
var imageSize = GetImageSize(imageId);
return GetCompatibleGrayImageBuffer(imageSize, GetSystemOfBuffer(imageId));
}
/// <summary>
/// 호환가능한 Gray이미지 버퍼 가져오기
/// </summary>
/// <param name="imageSize">이미지 사이즈</param>
/// <param name="boardType">보드 타입</param>
/// <param name="boardSlotPos">보드 슬롯 위치</param>
/// <returns>호환가능한 Gray 이미지 버퍼 MIL_ID</returns>
public static MIL_ID GetCompatibleGrayImageBuffer(ImageSize imageSize, eBoardType boardType, eBoardSlotPos boardSlotPos) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
return GetCompatibleGrayImageBuffer(imageSize, Instance.GetSystem(boardType, boardSlotPos));
}
/// <summary>
/// 호환가능한 Gray 이미지 버퍼 가져오기
/// </summary>
/// <param name="imageSize">이미지 사이즈</param>
/// <param name="systemId"> Mil 시스템 Id</param>
/// <returns>호환가능한 Gray 이미지 버퍼 MIL_ID</returns>
public static MIL_ID GetCompatibleGrayImageBuffer(ImageSize imageSize, MIL_ID systemId) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
MIL_ID grayImageId = MIL.M_NULL;
MIL.MbufAlloc2d(
systemId,
imageSize.Width,
imageSize.Height,
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref grayImageId);
MIL.MbufClear(grayImageId, 0);
return grayImageId;
}
/// <summary>
/// 호환가능한 Color 이미지 버퍼 가져오기
/// </summary>
/// <param name="imageId">이미지 버퍼 MIL_ID</param>
/// <returns>호환가능한 Color 이미지 버퍼 MIL_ID</returns>
public static MIL_ID GetCompatibleColorImageBuffer(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
var imageSize = GetImageSize(imageId);
return GetCompatibleColorImageBuffer(imageSize, GetSystemOfBuffer(imageId));
}
/// <summary>
/// 호환가능한 Color 이미지 버퍼 가져오기
/// </summary>
/// <param name="imageSize">이미지 사이즈</param>
/// <param name="boardType">보드 타입</param>
/// <param name="boardSlotPos">보드 슬롯 위치</param>
/// <returns>호환가능한 Color 이미지 버퍼 MIL_ID</returns>
public static MIL_ID GetCompatibleColorImageBuffer(ImageSize imageSize, eBoardType boardType, eBoardSlotPos boardSlotPos) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
return GetCompatibleColorImageBuffer(imageSize, Instance.GetSystem(boardType, boardSlotPos));
}
/// <summary>
/// 호환가능한 Color 이미지 버퍼 가져오기
/// </summary>
/// <param name="imageSize">이미지 사이즈</param>
/// <param name="systemId"> Mil 시스템 Id</param>
/// <returns>호환가능한 Color 이미지 버퍼 MIL_ID</returns>
public static MIL_ID GetCompatibleColorImageBuffer(ImageSize imageSize, MIL_ID systemId) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
MIL_ID imageBuffer = MIL.M_NULL;
MIL.MbufAllocColor(
systemId,
3,
imageSize.Width,
imageSize.Height,
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref imageBuffer);
MIL.MbufClear(imageBuffer, 0);
return imageBuffer;
}
/// <summary>
/// 이미지 크롭
/// </summary>
/// <param name="imageId">이미지 버퍼 MIL_ID</param>
/// <param name="roi"></param>
/// <returns></returns>
public static MIL_ID CropImage(MIL_ID imageId, Rect roi) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
ImageSize imageSize = GetImageSize(imageId);
if (imageSize.Width == roi.Width && imageSize.Height == roi.Height) {
return imageId;
}
else {
// roi의 Angle을 고려한 Crop API가 있으면 좋을 것 같음. 현재는 Crop시, Angle을 고려하지 않음.
return MIL.MbufChild2d(imageId, (int)roi.Left, (int)roi.Top, (int)roi.Width, (int)roi.Height, MIL.M_NULL);
}
}
/// <summary>
/// 이미지 크롭
/// </summary>
/// <param name="imageId">이미지 버퍼 MIL_ID</param>
/// <param name="roi"></param>
/// <returns></returns>
public static MIL_ID CropImage(MIL_ID imageId, ROI roi) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
var imageSize = GetImageSize(imageId);
if (imageSize.Width > roi.Width && imageSize.Height > roi.Height) {
// roi의 Angle을 고려한 Crop API가 있으면 좋을 것 같음. 현재는 Crop시, Angle을 고려하지 않음.
return MIL.MbufChild2d(imageId, (int)roi.Left, (int)roi.Top, (int)roi.Width, (int)roi.Height, MIL.M_NULL);
}
else {
return imageId;
}
}
/// <summary>
/// 이미지 리소스 회수
/// </summary>
/// <param name="imageId">이미지 ID</param>
/// <returns>성공 유무</returns>
public static int FreeImage(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return E1.GENERIC;
}
if (imageId != MIL.M_NULL) {
MIL.MbufFree(imageId);
}
return E1.OK;
}
/// <summary>
/// 이미지 리소스 회수
/// </summary>
/// <param name="imageId">이미지 ID</param>
/// <returns>성공 유무</returns>
public static int FreeImage(object imageId) {
if (!Instance.HasValidLicense()) {
return E1.GENERIC;
}
if (imageId != null) {
MIL.MbufFree((MIL_ID)imageId);
}
return E1.OK;
}
/// <summary>
/// Proc 이미지 배열 리소스 회수
/// </summary>
/// <param name="bufferSize">버퍼 사이즈</param>
/// <param name="images">Proc 이미지 배열</param>
/// <returns>성공 유무</returns>
public static int FreeProcImages(int bufferSize, object[] images) {
if (images == null) {
return E1.GENERIC;
}
for (int i = 0; i < bufferSize; i++) {
FreeImage((MIL_ID)images[i]);
}
return E1.OK;
}
/// <summary>
/// 사각형 중심 포인트 가져오기
/// </summary>
/// <param name="roi"></param>
/// <returns></returns>
public static ImagePoint GetRectCenter(Rect roi) {
return new ImagePoint(roi.Left + roi.Width / 2, roi.Top + roi.Height / 2);
}
/// <summary>
/// 이미지 중심 포인트 가져오기
/// </summary>
/// <param name="imageId">이미지 버퍼 MIL_ID</param>
/// <returns></returns>
public static ImagePoint GetImageCenter(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return new ImagePoint(0, 0);
}
var imageSize = GetImageSize(imageId);
return new ImagePoint(
imageSize.Width * 0.5,
imageSize.Height * 0.5);
}
/// <summary>
/// 이미지 사이즈 가져오기
/// </summary>
/// <param name="imageId">이미지 버퍼 MIL_ID</param>
/// <returns>이미지 사이즈</returns>
public static ImageSize GetImageSize(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return new ImageSize();
}
int width = -1;
int height = -1;
int band = -1;
int bitDepth = -1;
try {
width = (int)MIL.MbufInquire(imageId, MIL.M_SIZE_X);
height = (int)MIL.MbufInquire(imageId, MIL.M_SIZE_Y);
band = (int)MIL.MbufInquire(imageId, MIL.M_SIZE_BAND);
bitDepth = (int)MIL.MbufInquire(imageId, MIL.M_SIZE_BIT);
}
catch (Exception e) {
}
return new ImageSize() {
Width = width,
Height = height,
Channel = band,
BitDepth = bitDepth
};
}
/// <summary>
/// 이미지 사이즈 가져오기
/// </summary>
/// <param name="camConfig">카메라 컨피그</param>
/// <returns>성공 유무</returns>
public ImageSize GetImageSize(CamConfig camConfig) {
var imageSize = new ImageSize();
if (IsHeightLongerThanWidth(camConfig)) {
imageSize.Width = (int)(camConfig.ImageSize.Height * camConfig.ImageSizeRatioY);
imageSize.Height = (int)(camConfig.ImageSize.Width * camConfig.ImageSizeRatioX);
}
else {
imageSize.Width = (int)(camConfig.ImageSize.Width * camConfig.ImageSizeRatioX);
imageSize.Height = (int)(camConfig.ImageSize.Height * camConfig.ImageSizeRatioY);
}
imageSize.Channel = camConfig.ImageSize.Channel;
imageSize.BitDepth = camConfig.ImageSize.BitDepth;
return imageSize;
}
/// <summary>
/// 이미지 사이즈 동일 여부 체크
/// </summary>
/// <param name="image1">이미지1</param>
/// <param name="image2">이미지2</param>
/// <returns>이미지 사이즈 동일 여부</returns>
public static bool ImageSizeEquals(MIL_ID image1, MIL_ID image2) {
var imageSize1 = GetImageSize(image1);
var imageSize2 = GetImageSize(image2);
return ImageSizeEquals(imageSize1, imageSize2);
}
/// <summary>
/// 이미지 사이즈 동일 여부 체크
/// </summary>
/// <param name="imageSize1">이미지 사이즈 1</param>
/// <param name="imageSize2">이미지 사이즈 2</param>
/// <returns>이미지 사이즈 동일 여부</returns>
public static bool ImageSizeEquals(ImageSize imageSize1, ImageSize imageSize2) {
if (imageSize1.Width != imageSize2.Width ||
imageSize1.Height != imageSize2.Height ||
imageSize1.BitDepth != imageSize2.BitDepth ||
imageSize1.Channel != imageSize2.Channel) {
return false;
}
return true;
}
/// <summary>
/// 이미지 사이즈 Null인지 여부
/// </summary>
/// <param name="imageSize">이미지 사이즈</param>
/// <returns>True : Null</returns>
public static bool IsImageSizeNull(ImageSize imageSize) {
if (imageSize.Width == -1 && imageSize.Height == -1) {
return true;
}
else {
return false;
}
}
/// <summary>
/// 이미지가 Color인지 여부
/// </summary>
/// <param name="imageId">이미지 버퍼 MIL_ID</param>
/// <returns>True : ColorImage</returns>
public static bool IsColorImage(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return false;
}
var imageSize = GetImageSize(imageId);
return (imageSize.Channel != 1);
}
/// <summary>
/// Mil 이미지를 byte array로 변환
/// </summary>
/// <param name="imageId">이미지 버퍼 MIL_ID</param>
/// <returns>변환된 이미지 byte array</returns>
public static byte[] ConvertMilToByteArry(MIL_ID imageId) {
ImageSize imageSize = GetImageSize(imageId);
byte[] byteArry = new byte[imageSize.Width * imageSize.Height * imageSize.Channel];
MIL.MbufGet2d(imageId, 0, 0, imageSize.Width, imageSize.Height, byteArry);
return byteArry;
}
/// <summary>
/// byte array를 mil 이미지 로 변환
/// </summary>
/// <param name="byteArry"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="imageId">이미지 버퍼 MIL_ID</param>
public static void ConvertByteArryToMil(byte[] byteArry, int width, int height, ref MIL_ID imageId) {
var imageSize = GetImageSize(imageId);
if (imageSize.Channel == 3) {
MIL.MbufPutColor2d(imageId, MIL.M_PACKED + MIL.M_BGR24, MIL.M_ALL_BANDS, 0, 0, width, height, byteArry);
}
else {
MIL.MbufPut2d(imageId, 0, 0, width, height, byteArry);
}
}
/// <summary>
/// color 이미지를 gray 이미지로 변환
/// </summary>
/// <param name="colorImageId"></param>
/// <returns></returns>
public static MIL_ID ConvertToGray(MIL_ID colorImageId) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
MIL_ID grayImageId = GetCompatibleGrayImageBuffer(colorImageId);
ConvertToGray(colorImageId, grayImageId);
return grayImageId;
}
/// <summary>
/// color 이미지를 gray 이미지로 변환
/// </summary>
/// <param name="colorImageId"></param>
/// <param name="grayImageId"></param>
/// <returns></returns>
public static int ConvertToGray(MIL_ID colorImageId, MIL_ID grayImageId) {
if (!Instance.HasValidLicense()) {
return E1.GENERIC;
}
MIL.MimConvert(colorImageId, grayImageId, MIL.M_RGB_TO_L);
return E1.OK;
}
/// <summary>
/// gray 이미지를 rgb 이미지로 변환
/// </summary>
/// <param name="imageId">이미지 버퍼 MIL_ID</param>
/// <param name="boardType">보드 타입</param>
/// <param name="boardSlotPos">보드 슬롯 위치</param>
/// <returns></returns>
public static MIL_ID ConvertGrayToRGB(MIL_ID imageId, eBoardType boardType, eBoardSlotPos boardSlotPos) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
var imageSize = GetImageSize(imageId);
if (IsColorImage(imageSize)) {
return CloneImage(imageId);
}
else {
MIL_ID rgbImageId = MIL.M_NULL;
MIL.MbufAllocColor(
Instance.GetSystem(boardType, boardSlotPos),
3,
imageSize.Width,
imageSize.Height,
8 + MIL.M_UNSIGNED,
MIL.M_IMAGE + MIL.M_GRAB + MIL.M_PROC + MIL.M_DISP,
ref rgbImageId);
MIL.MbufCopyColor(imageId, rgbImageId, MIL.M_RED);
MIL.MbufCopyColor(imageId, rgbImageId, MIL.M_GREEN);
MIL.MbufCopyColor(imageId, rgbImageId, MIL.M_BLUE);
return rgbImageId;
}
}
/// <summary>
/// mil 이미지를 bitmap 이미지로 변환
/// </summary>
/// <param name="image">이미지</param>
/// <returns></returns>
public static Bitmap ConvertToBitmap(MIL_ID image) {
if (image == MIL.M_NULL) {
return ThumbnailUtil.GetDefaultImage();
}
try {
var imageSize = GetImageSize(image);
byte[] byteData = new byte[imageSize.Width * imageSize.Height * imageSize.Channel];
Bitmap bitmap;
if (imageSize.Channel == 3) {
MIL.MbufGetColor2d(
image, MIL.M_PACKED + MIL.M_RGB24, MIL.M_ALL_BANDS, 0, 0, imageSize.Width, imageSize.Height, byteData);
bitmap = new Bitmap(imageSize.Width, imageSize.Height, PixelFormat.Format24bppRgb);
}
else {
MIL.MbufGet2d(image, 0, 0, imageSize.Width, imageSize.Height, byteData);
bitmap = new Bitmap(imageSize.Width, imageSize.Height, PixelFormat.Format8bppIndexed);
// 팔레트 설정 (그레이스케일)
ColorPalette palette = bitmap.Palette;
for (int i = 0; i < 256; i++) {
palette.Entries[i] = Color.FromArgb(i, i, i);
}
bitmap.Palette = palette;
}
var rowLength = bitmap.Width * imageSize.Channel;
var bitmapData = bitmap.LockBits(
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.WriteOnly,
bitmap.PixelFormat);
for (int h = 0; h < bitmap.Height; h++) {
Marshal.Copy(
byteData,
h * rowLength,
bitmapData.Scan0 + (h * bitmapData.Stride),
rowLength);
}
bitmap.UnlockBits(bitmapData);
return bitmap;
}
catch (Exception e) {
_Logger.FuncE(e.Message);
}
return ThumbnailUtil.GetDefaultImage();
}
/// <summary>
/// 컬러 이미지인지 여부
/// </summary>
/// <param name="imageSize">이미지 사이즈</param>
/// <returns></returns>
public static bool IsColorImage(ImageSize imageSize) {
return imageSize.Channel != 1;
}
/// <summary>
/// 이미지 픽셀 클리어
/// </summary>
/// <param name="image">이미지</param>
public static void ClearImage(MIL_ID image) {
if (!Instance.HasValidLicense()) {
return;
}
if (image != MIL.M_NULL) {
MIL.MbufClear(image, 0);
}
}
/// <summary>
/// 이미지 픽셀 클리어
/// </summary>
/// <param name="image">이미지</param>
public static void ClearImage(object image) {
if (!Instance.HasValidLicense()) {
return;
}
if (image != null) {
MIL.MbufClear((MIL_ID)image, 0);
}
}
/// <summary>
/// 이미지의 ROI 내에서 Pixel Sharpness 값 가져오기
/// </summary>
/// <param name="image">이미지</param>
/// <param name="cropRoi">Rect</param>
/// <returns>Pixel Sharpness 값</returns>
public static int GetSharpnessWithCropRoi(MIL_ID image, Rect cropRoi) {
MIL_ID cropImage = CropImage(image, cropRoi);
return GetSharpness(cropImage);
}
/// <summary>
/// 이미지의 ROI 내에서 Pixel Sharpness 값 가져오기
/// </summary>
/// <param name="image">이미지</param>
/// <param name="cropRoi">ROI</param>
/// <returns>Pixel Sharpness 값</returns>
public static int GetSharpnessWithCropRoi(MIL_ID image, ROI cropRoi) {
MIL_ID cropImage = CropImage(image, cropRoi);
return GetSharpness(cropImage);
}
/// <summary>
/// 이미지 내에서 Pixel Sharpness 값 가져오기
/// </summary>
/// <param name="image">이미지</param>
/// <returns>Pixel Sharpness 값</returns>
public static int GetSharpness(MIL_ID image) {
MIL_INT sharpness = 0;
MIL.MdigFocus(MIL.M_NULL, image, MIL.M_DEFAULT,
null, MIL.M_NULL, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_DEFAULT, MIL.M_EVALUATE, ref sharpness);
return (int)sharpness;
}
/// <summary>
/// 이미지의 ROI 내에서 Pixel Brightness 값 가져오기
/// </summary>
/// <param name="image">이미지</param>
/// <param name="cropRoi">Rect</param>
/// <returns>Pixel Brightness 값</returns>
public static BrightnessResult GetBrightnessWithCropRoi(MIL_ID image, Rect cropRoi) {
MIL_ID cropImage = CropImage(image, cropRoi);
return GetBrightness(cropImage, GetRectCenter(cropRoi));
}
/// <summary>
/// 이미지의 ROI 내에서 Pixel Brightness 값 가져오기
/// </summary>
/// <param name="image">이미지</param>
/// <param name="cropRoi">ROI</param>
/// <returns>Pixel Brightness 값</returns>
public static BrightnessResult GetBrightnessWithCropRoi(MIL_ID image, ROI cropRoi) {
MIL_ID cropImage = CropImage(image, cropRoi);
return GetBrightness(cropImage, cropRoi.Center);
}
/// <summary>
/// 이미지 Point에서 Pixel Brightness 값 가져오기
/// </summary>
/// <param name="image">이미지</param>
/// <param name="imagePoint">이미지 포인트</param>
/// <returns>Pixel Brightness 값</returns>
public static BrightnessResult GetBrightness(MIL_ID image, ImagePoint imagePoint) {
MIL_ID contextId = MIL.M_NULL;
MIL_ID resultBufId = MIL.M_NULL;
MIL_INT min = 0;
MIL_INT max = 0;
MIL_INT avg = 0;
MIL.MimAlloc(GetSystemOfBuffer(image), MIL.M_STATISTICS_CONTEXT, MIL.M_DEFAULT, ref contextId);
MIL.MimAllocResult(GetSystemOfBuffer(image), MIL.M_DEFAULT, MIL.M_STATISTICS_RESULT, ref resultBufId);
MIL.MimControl(contextId, MIL.M_STAT_MIN, MIL.M_ENABLE);
MIL.MimControl(contextId, MIL.M_STAT_MAX, MIL.M_ENABLE);
MIL.MimControl(contextId, MIL.M_STAT_MEAN, MIL.M_ENABLE);
MIL.MimStatCalculate(contextId, image, resultBufId, MIL.M_DEFAULT);
MIL.MimGetResult(resultBufId, MIL.M_STAT_MIN + MIL.M_TYPE_MIL_INT, ref min);
MIL.MimGetResult(resultBufId, MIL.M_STAT_MAX + MIL.M_TYPE_MIL_INT, ref max);
MIL.MimGetResult(resultBufId, MIL.M_STAT_MEAN + MIL.M_TYPE_MIL_INT, ref avg);
MIL.MimFree(resultBufId);
MIL.MimFree(contextId);
return new BrightnessResult(
imagePoint,
(int)min, (int)max, (int)avg);
}
/// <summary>
/// Overlay 이미지 가져오기
/// </summary>
/// <param name="milCameraDisplay">mil 카메라 디스플레이</param>
/// <param name="grabImage">그랩 이미지</param>
/// <returns>Overlay 이미지</returns>
public static MIL_ID GetOverlayImage(IMilCameraDisplay milCameraDisplay, object grabImage = null) {
MIL_ID image = MIL.M_NULL;
if (grabImage == null) {
image = milCameraDisplay.GetImage();
}
else {
image = (MIL_ID)grabImage;
}
var overlayImage = GetCompatibleColorImageBuffer(image);
CopyImage(image, overlayImage);
MIL.MgraDraw(milCameraDisplay.GetGraphicListId(), overlayImage, MIL.M_DEFAULT);
return overlayImage;
}
/// <summary>
/// Overlay 이미지 저장
/// </summary>
/// <param name="filePath">파일 경로</param>
/// <param name="fovInfos">모든 FOV 정보</param>
/// <param name="displayType">디스플레이 타입</param>
/// <param name="image">이미지 default:Null</param>
/// <returns>성공 유무</returns>
public static int SaveScreenShot(string filePath, List<FovInfo> fovInfos, eDisplayType displayType, object image = null) {
var overlayImages = new Dictionary<FovInfo, MIL_ID>();
MIL_ID screenShotImage = MIL.M_NULL;
try {
foreach (var fovInfo in fovInfos) {
var milCameraDisplay = CameraDisplayManager.GetDisplay(fovInfo, displayType) as IMilCameraDisplay;
var overlayImage = GetOverlayImage(milCameraDisplay, image);
overlayImages[fovInfo] = overlayImage;
}
if (0 < overlayImages.Count) {
var screenShotImageSize = GetScreenShotImageSize(overlayImages, displayType);
if (screenShotImageSize == null) {
return E1.GENERIC;
}
screenShotImage = GetCompatibleColorImageBuffer(screenShotImageSize, GetSystemOfBuffer(overlayImages.Values.ToList()[0]));
var (ltFovInfo, ltFovUiPos) = ScreenShotUtil.GetLeftTopFovInfo(overlayImages.Keys.ToList(), displayType);
var (ltFovUiPosRow, ltFovUiPosCol) = FovRecipe.GetFovUiPosRowCol(ltFovUiPos);
foreach (var fovInfo in fovInfos) {
var fovRecipe = VisionRecipeManager.GetFovRecipe(fovInfo);
eFovUiPos fovUiPos = new eFovUiPos();
foreach (var mainUiRecipe in fovRecipe.MainUiRecipes) {
if (mainUiRecipe.MainDisplayType == displayType) {
fovUiPos = mainUiRecipe.FovUiPos;
}
}
var (curFovUiPosRow, curFovUiPosCol) = FovRecipe.GetFovUiPosRowCol(fovUiPos);
var imageSize = GetImageSize(overlayImages[fovInfo]);
MIL.MbufCopyClip(
overlayImages[fovInfo],
screenShotImage,
(curFovUiPosCol - ltFovUiPosCol) * imageSize.Width,
(curFovUiPosRow - ltFovUiPosRow) * imageSize.Height);
}
SaveImage(filePath, screenShotImage);
}
}
catch (Exception e) {
_Logger.E(e.Message);
}
finally {
FreeImage(screenShotImage);
foreach (var overlayImage in overlayImages.Values) {
FreeImage(overlayImage);
}
}
return E1.OK;
}
private static ImageSize GetScreenShotImageSize(Dictionary<FovInfo, MIL_ID> overlayImages, eDisplayType displayType) {
if (0 < overlayImages.Count && 0 < overlayImages.Count) {
var (ltFovInfo, ltFovUiPos) = ScreenShotUtil.GetLeftTopFovInfo(overlayImages.Keys.ToList(), displayType);
if (ltFovInfo == null) {
return null;
}
var imageSize = GetImageSize(overlayImages[ltFovInfo]);
imageSize.Channel = 3;
if (ScreenShotUtil.HasRightFov(ltFovInfo, ltFovUiPos, overlayImages.Keys.ToList(), displayType)) {
imageSize.Width *= 2;
}
if (ScreenShotUtil.HasBottomFov(ltFovInfo, ltFovUiPos, overlayImages.Keys.ToList(), displayType)) {
imageSize.Height *= 2;
}
return imageSize;
}
return null;
}
}
}