/*
* 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 {
///
/// MIL 환경 변수 및 메소드 관리
///
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 DisplayList;
public MIL_ID Application { get; private set; }
// M_DEFAULT를 사용하는 경우, 시스템을 _DefaultSys 1개만 할당한다.
private MIL_ID _DefaultSys;
// M_DEFAULT가 아닐 경우, 시스템을 BoardType & Slot의 개수만큼 할당한다.
private Dictionary> Systems { get; set; }
= new Dictionary>();
private static MilEnvironment _instance = null;
///
/// 싱글톤 객체
///
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();
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;
}
}
///
/// MIL 시스템 가져오기
///
/// 보드 타입
/// 보드 슬롯 위치
/// MIL 시스템
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;
}
///
/// MIL 시스템 할당 여부 체크
///
/// 보드 타입
/// 보드 슬롯 위치
///
public bool IsSysAllocated(eBoardType boardType, eBoardSlotPos boardSlotPos) {
if (Systems.ContainsKey(boardType)) {
if (Systems[boardType].ContainsKey(boardSlotPos)) {
return true;
}
}
return false;
}
///
/// 이미지로 MIL 시스템 가져오기
///
/// 이미지
/// MIL 시스템
public static MIL_ID GetSystemOfBuffer(MIL_ID image) {
return (MIL_ID)MIL.MbufInquire(image, MIL.M_OWNER_SYSTEM, MIL.M_NULL);
}
///
/// MIL 시스템 할당
///
/// 보드 타입
/// 보드 슬롯 위치
public void AllocSys(eBoardType boardType, eBoardSlotPos boardSlotPos) {
try {
lock (LockObj) {
if (IsSysAllocated(boardType, boardSlotPos)) {
return;
}
if (!Systems.ContainsKey(boardType)) {
Systems.Add(boardType, new Dictionary());
}
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;
}
}
///
/// MIL 라이센스 체크
///
/// 라이센스 여부
public bool HasValidLicense() {
return (_LicenseModules & MIL.M_LICENSE_MOD) != 0;
}
///
/// 디스플레이 생성
///
/// 윈폼 핸들러(IntPtr)
/// 이미지 버퍼 Mil_ID
/// Display ID (MIL_ID)
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;
}
}
///
/// 해당 디스플레이 선택
///
/// 윈폼 핸들러(IntPtr)
/// 이미지 버퍼 Mil_ID
/// 선택할 Display Id (MIL_ID)
public void SelectDisplay(IntPtr WinFormHandle, MIL_ID imageBuffer, MIL_ID displayId) {
if (!Instance.HasValidLicense()) {
return;
}
lock (LockObj) {
MIL.MdispSelectWindow(displayId, imageBuffer, WinFormHandle);
}
}
///
/// 디스플레이 해제/제거
///
/// 해제할 Display Id (MIL_ID)
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);
}
}
///
/// 원본 이미지 버퍼 할당
///
/// 카메라 컨피그
/// 원본 이미지 버퍼
/// 성공 유무
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;
}
}
///
/// Flip & Rotation 이미지 버퍼 할당
///
/// 카메라 컨피그
/// Flip & Rotation 이미지 버퍼
/// 성공 유무
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;
}
}
}
///
/// Crop 이미지 버퍼 할당
///
/// 카메라 컨피그
/// Crop 이미지 버퍼
/// 성공 유무
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;
}
}
}
///
/// Dig Process 이미지 배열 할당
///
/// 카메라 컨피그
/// 버퍼 사이즈
/// Proc 이미지 버퍼 배열
///
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;
}
///
/// Child 이미지 할당
///
/// 카메라 컨피그
/// 부모 이미지 버퍼
/// 자식 이미지 버퍼 배열
///
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;
}
///
/// Child 이미지 사용시, 부모 이미지 버퍼 할당
///
/// 카메라 컨피그
/// 부모 이미지 버퍼
/// 성공 유무
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;
}
///
/// 이미지 반전 유무 확인
///
/// 카메라 컨피그
/// 이미지 반전 유무
public bool IsFlipEnabled(CamConfig camConfig) {
if (camConfig.FlipAndRotation.ImageFlip.Equals(eImageFlip.None))
return false;
else
return true;
}
///
/// 이미지 회전 유무 확인
///
/// 카메라 컨피그
/// 이미지 회전 유무
public bool IsRotationEnabled(CamConfig camConfig) {
if (camConfig.FlipAndRotation.ImageRotation.Equals(eImageRotation.None) &&
camConfig.FlipAndRotation.ImageRotationOffset == 0)
return false;
else
return true;
}
///
/// 이미지 세로 사이즈가 가로 사이즈보다 큰지 확인
///
/// 카메라 컨피그
/// 이미지 세로 사이즈가 가로 사이즈보다 크면 True
public bool IsHeightLongerThanWidth(CamConfig camConfig) {
switch (camConfig.FlipAndRotation.ImageRotation) {
case eImageRotation.CW_DEG_90:
case eImageRotation.CW_DEG_270:
return true;
}
return false;
}
///
/// 이미지 저장
///
/// 파일경로
/// 이미지버퍼 MIL_ID
/// 크롭(저장) 할 영역
/// 성공 유무
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;
}
///
/// 이미지 저장
///
/// 파일경로
/// 이미지버퍼 MIL_ID
/// 성공 유무
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;
}
///
/// 이미지 로드
///
/// 불러올 이미지 경로
/// 보드 타입
/// 보드 슬롯 위치
/// 이미지 버퍼 MIL_ID
public static MIL_ID LoadImage(string filePath, CamConfig camConfig) {
return LoadImage(filePath, Instance.GetSystem(camConfig.CamConnConfig.BoardType, camConfig.CamConnConfig.BoardSlotPos));
}
///
/// 이미지 로드
///
/// 불러올 이미지 경로
/// Mil 시스템 Id
/// 이미지 버퍼 MIL_ID
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;
}
///
/// 이미지 복사
///
/// 소스 이미지 버퍼
/// 목적지 이미지 버퍼
/// 성공 유무
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;
}
///
/// 버퍼 카피 가능한지 여부
///
/// 소스 이미지 버퍼
/// 목적지 이미지 버퍼
///
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;
}
///
/// 이미지 복제
///
/// 복제할 이미지 ID
/// 복제된 이미지 MIL_ID
public static MIL_ID CloneImage(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
return CloneImage(imageId, GetSystemOfBuffer(imageId));
}
///
/// 이미지 복제
///
/// 복제할 이미지 ID
/// MIL 시스템 ID
/// 복제된 이미지 MIL_ID
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);
}
///
/// 호환가능한 이미지 버퍼 가져오기
///
/// 이미지 버퍼 MIL_ID
/// 호환가능한 이미지 버퍼 MIL_ID
public static MIL_ID GetCompatibleImageBuffer(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
var imageSize = GetImageSize(imageId);
return GetCompatibleImageBuffer(imageSize, GetSystemOfBuffer(imageId));
}
///
/// 호환가능한 이미지 버퍼 가져오기
///
/// 이미지 사이즈
/// 보드 타입
/// 보드 슬롯 위치
/// 호환가능한 이미지 버퍼 MIL_ID
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));
}
///
/// 호환가능한 이미지 버퍼 가져오기
///
/// 이미지 사이즈
/// Mil 시스템 Id
/// 호환가능한 이미지 버퍼 MIL_ID
public static MIL_ID GetCompatibleImageBuffer(ImageSize imageSize, MIL_ID systemId) {
if (imageSize.Channel == 1) {
return GetCompatibleGrayImageBuffer(imageSize, systemId);
}
else {
return GetCompatibleColorImageBuffer(imageSize, systemId);
}
}
///
/// 호환가능한 Gray 이미지 버퍼 가져오기
///
/// 이미지 버퍼 MIL_ID
/// 호환가능한 Gray 이미지 버퍼 MIL_ID
public static MIL_ID GetCompatibleGrayImageBuffer(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
var imageSize = GetImageSize(imageId);
return GetCompatibleGrayImageBuffer(imageSize, GetSystemOfBuffer(imageId));
}
///
/// 호환가능한 Gray이미지 버퍼 가져오기
///
/// 이미지 사이즈
/// 보드 타입
/// 보드 슬롯 위치
/// 호환가능한 Gray 이미지 버퍼 MIL_ID
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));
}
///
/// 호환가능한 Gray 이미지 버퍼 가져오기
///
/// 이미지 사이즈
/// Mil 시스템 Id
/// 호환가능한 Gray 이미지 버퍼 MIL_ID
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;
}
///
/// 호환가능한 Color 이미지 버퍼 가져오기
///
/// 이미지 버퍼 MIL_ID
/// 호환가능한 Color 이미지 버퍼 MIL_ID
public static MIL_ID GetCompatibleColorImageBuffer(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return MIL.M_NULL;
}
var imageSize = GetImageSize(imageId);
return GetCompatibleColorImageBuffer(imageSize, GetSystemOfBuffer(imageId));
}
///
/// 호환가능한 Color 이미지 버퍼 가져오기
///
/// 이미지 사이즈
/// 보드 타입
/// 보드 슬롯 위치
/// 호환가능한 Color 이미지 버퍼 MIL_ID
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));
}
///
/// 호환가능한 Color 이미지 버퍼 가져오기
///
/// 이미지 사이즈
/// Mil 시스템 Id
/// 호환가능한 Color 이미지 버퍼 MIL_ID
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;
}
///
/// 이미지 크롭
///
/// 이미지 버퍼 MIL_ID
///
///
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);
}
}
///
/// 이미지 크롭
///
/// 이미지 버퍼 MIL_ID
///
///
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;
}
}
///
/// 이미지 리소스 회수
///
/// 이미지 ID
/// 성공 유무
public static int FreeImage(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return E1.GENERIC;
}
if (imageId != MIL.M_NULL) {
MIL.MbufFree(imageId);
}
return E1.OK;
}
///
/// 이미지 리소스 회수
///
/// 이미지 ID
/// 성공 유무
public static int FreeImage(object imageId) {
if (!Instance.HasValidLicense()) {
return E1.GENERIC;
}
if (imageId != null) {
MIL.MbufFree((MIL_ID)imageId);
}
return E1.OK;
}
///
/// Proc 이미지 배열 리소스 회수
///
/// 버퍼 사이즈
/// Proc 이미지 배열
/// 성공 유무
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;
}
///
/// 사각형 중심 포인트 가져오기
///
///
///
public static ImagePoint GetRectCenter(Rect roi) {
return new ImagePoint(roi.Left + roi.Width / 2, roi.Top + roi.Height / 2);
}
///
/// 이미지 중심 포인트 가져오기
///
/// 이미지 버퍼 MIL_ID
///
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);
}
///
/// 이미지 사이즈 가져오기
///
/// 이미지 버퍼 MIL_ID
/// 이미지 사이즈
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
};
}
///
/// 이미지 사이즈 가져오기
///
/// 카메라 컨피그
/// 성공 유무
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;
}
///
/// 이미지 사이즈 동일 여부 체크
///
/// 이미지1
/// 이미지2
/// 이미지 사이즈 동일 여부
public static bool ImageSizeEquals(MIL_ID image1, MIL_ID image2) {
var imageSize1 = GetImageSize(image1);
var imageSize2 = GetImageSize(image2);
return ImageSizeEquals(imageSize1, imageSize2);
}
///
/// 이미지 사이즈 동일 여부 체크
///
/// 이미지 사이즈 1
/// 이미지 사이즈 2
/// 이미지 사이즈 동일 여부
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;
}
///
/// 이미지 사이즈 Null인지 여부
///
/// 이미지 사이즈
/// True : Null
public static bool IsImageSizeNull(ImageSize imageSize) {
if (imageSize.Width == -1 && imageSize.Height == -1) {
return true;
}
else {
return false;
}
}
///
/// 이미지가 Color인지 여부
///
/// 이미지 버퍼 MIL_ID
/// True : ColorImage
public static bool IsColorImage(MIL_ID imageId) {
if (!Instance.HasValidLicense()) {
return false;
}
var imageSize = GetImageSize(imageId);
return (imageSize.Channel != 1);
}
///
/// Mil 이미지를 byte array로 변환
///
/// 이미지 버퍼 MIL_ID
/// 변환된 이미지 byte array
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;
}
///
/// byte array를 mil 이미지 로 변환
///
///
///
///
/// 이미지 버퍼 MIL_ID
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);
}
}
///
/// color 이미지를 gray 이미지로 변환
///
///
///
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;
}
///
/// color 이미지를 gray 이미지로 변환
///
///
///
///
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;
}
///
/// gray 이미지를 rgb 이미지로 변환
///
/// 이미지 버퍼 MIL_ID
/// 보드 타입
/// 보드 슬롯 위치
///
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;
}
}
///
/// mil 이미지를 bitmap 이미지로 변환
///
/// 이미지
///
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();
}
///
/// 컬러 이미지인지 여부
///
/// 이미지 사이즈
///
public static bool IsColorImage(ImageSize imageSize) {
return imageSize.Channel != 1;
}
///
/// 이미지 픽셀 클리어
///
/// 이미지
public static void ClearImage(MIL_ID image) {
if (!Instance.HasValidLicense()) {
return;
}
if (image != MIL.M_NULL) {
MIL.MbufClear(image, 0);
}
}
///
/// 이미지 픽셀 클리어
///
/// 이미지
public static void ClearImage(object image) {
if (!Instance.HasValidLicense()) {
return;
}
if (image != null) {
MIL.MbufClear((MIL_ID)image, 0);
}
}
///
/// 이미지의 ROI 내에서 Pixel Sharpness 값 가져오기
///
/// 이미지
/// Rect
/// Pixel Sharpness 값
public static int GetSharpnessWithCropRoi(MIL_ID image, Rect cropRoi) {
MIL_ID cropImage = CropImage(image, cropRoi);
return GetSharpness(cropImage);
}
///
/// 이미지의 ROI 내에서 Pixel Sharpness 값 가져오기
///
/// 이미지
/// ROI
/// Pixel Sharpness 값
public static int GetSharpnessWithCropRoi(MIL_ID image, ROI cropRoi) {
MIL_ID cropImage = CropImage(image, cropRoi);
return GetSharpness(cropImage);
}
///
/// 이미지 내에서 Pixel Sharpness 값 가져오기
///
/// 이미지
/// Pixel Sharpness 값
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;
}
///
/// 이미지의 ROI 내에서 Pixel Brightness 값 가져오기
///
/// 이미지
/// Rect
/// Pixel Brightness 값
public static BrightnessResult GetBrightnessWithCropRoi(MIL_ID image, Rect cropRoi) {
MIL_ID cropImage = CropImage(image, cropRoi);
return GetBrightness(cropImage, GetRectCenter(cropRoi));
}
///
/// 이미지의 ROI 내에서 Pixel Brightness 값 가져오기
///
/// 이미지
/// ROI
/// Pixel Brightness 값
public static BrightnessResult GetBrightnessWithCropRoi(MIL_ID image, ROI cropRoi) {
MIL_ID cropImage = CropImage(image, cropRoi);
return GetBrightness(cropImage, cropRoi.Center);
}
///
/// 이미지 Point에서 Pixel Brightness 값 가져오기
///
/// 이미지
/// 이미지 포인트
/// Pixel Brightness 값
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);
}
///
/// Overlay 이미지 가져오기
///
/// mil 카메라 디스플레이
/// 그랩 이미지
/// Overlay 이미지
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;
}
///
/// Overlay 이미지 저장
///
/// 파일 경로
/// 모든 FOV 정보
/// 디스플레이 타입
/// 이미지 default:Null
/// 성공 유무
public static int SaveScreenShot(string filePath, List fovInfos, eDisplayType displayType, object image = null) {
var overlayImages = new Dictionary();
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 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;
}
}
}