777 {
779 data = File.ReadAllBytes(path);
780 size = data.Length;
781 if (getByte(0) != 73 || getByte(1) != 111)
782 throw new IOException("This is not an ImageJ ROI");
783 int version = getShort(VERSION_OFFSET);
784 int type = getByte(TYPE);
785 int subtype = getShort(SUBTYPE);
786 int top = getShort(TOP);
787 int left = getShort(LEFT);
788 int bottom = getShort(BOTTOM);
789 int right = getShort(RIGHT);
790 int width = right - left;
791 int height = bottom - top;
792 int n = getUnsignedShort(N_COORDINATES);
793 if (n == 0)
794 n = getInt(SIZE);
795 int options = getShort(OPTIONS);
796 int position = getInt(POSITION);
797 int hdr2Offset = getInt(HEADER2_OFFSET);
798 int channel = 0, slice = 0, frame = 0;
799 int overlayLabelColor = 0;
800 int overlayFontSize = 0;
801 int group = 0;
802 int imageOpacity = 0;
803 int imageSize = 0;
804 bool subPixelResolution = (options & SUB_PIXEL_RESOLUTION) != 0 && version >= 222;
805 bool drawOffset = subPixelResolution && (options & DRAW_OFFSET) != 0;
806 bool scaleStrokeWidth = true;
807 if (version >= 228)
808 scaleStrokeWidth = (options & SCALE_STROKE_WIDTH) != 0;
809
810 bool subPixelRect = version >= 223 && subPixelResolution && (type == rect || type == oval);
811 double xd = 0.0, yd = 0.0, widthd = 0.0, heightd = 0.0;
812 if (subPixelRect)
813 {
814 xd = getFloat(XD);
815 yd = getFloat(YD);
816 widthd = getFloat(WIDTHD);
817 heightd = getFloat(HEIGHTD);
818 roi.subPixel = true;
819 }
820
821 if (hdr2Offset > 0 && hdr2Offset + IMAGE_SIZE + 4 <= size)
822 {
823 channel = getInt(hdr2Offset + C_POSITION);
824 slice = getInt(hdr2Offset + Z_POSITION);
825 frame = getInt(hdr2Offset + T_POSITION);
826 overlayLabelColor = getInt(hdr2Offset + OVERLAY_LABEL_COLOR);
827 overlayFontSize = getShort(hdr2Offset + OVERLAY_FONT_SIZE);
828 imageOpacity = getByte(hdr2Offset + IMAGE_OPACITY);
829 imageSize = getInt(hdr2Offset + IMAGE_SIZE);
830 group = getByte(hdr2Offset + GROUP);
831 }
832
833 if (name != null && name.EndsWith(".roi"))
834 name = name.Substring(0, name.Length - 4);
835 bool isComposite = getInt(SHAPE_ROI_SIZE) > 0;
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861 switch (type)
862 {
863 case 1:
864 if (subPixelRect)
865 roi =
ROI.
CreateRectangle(
new AForge.ZCT(slice - 1, channel - 1, frame - 1), xd, yd, widthd, heightd);
866 else
867 roi =
ROI.
CreateRectangle(
new AForge.ZCT(slice - 1, channel - 1, frame - 1), left, top, width, height);
868 int arcSize = getShort(ROUNDED_RECT_ARC_SIZE);
869 if (arcSize > 0)
870 throw new NotSupportedException("Type rounded rectangle not supported.");
871 break;
872 case 2:
873 if (subPixelRect)
874 roi =
ROI.
CreateEllipse(
new AForge.ZCT(slice - 1, channel - 1, frame - 1), xd, yd, widthd, heightd);
875 else
876 roi =
ROI.
CreateEllipse(
new AForge.ZCT(slice - 1, channel - 1, frame - 1), left, top, width, height);
877 break;
878 case 3:
879 float x1 = getFloat(X1);
880 float y1 = getFloat(Y1);
881 float x2 = getFloat(X2);
882 float y2 = getFloat(Y2);
883
884 if (subtype == ARROW)
885 {
886 throw new NotSupportedException("Type arrow not supported.");
887
888
889
890
891
892
893
894
895
896
897
898 }
899 else
900 {
901 roi =
ROI.
CreateLine(
new AForge.ZCT(slice, channel, frame),
new AForge.PointD(x1, y1),
new AForge.PointD(x2, y2));
902
903 }
904
905 break;
906 case 0:
907 case 5:
908 case 6:
909 case 7:
910 case 8:
911 case 9:
912 case 10:
913
914
915
916 if (n == 0 || n < 0) break;
917 int[] x = new int[n];
918 int[] y = new int[n];
919 float[] xf = null;
920 float[] yf = null;
921 int base1 = COORDINATES;
922 int base2 = base1 + 2 * n;
923 int xtmp, ytmp;
924 for (int i = 0; i < n; i++)
925 {
926 xtmp = getShort(base1 + i * 2);
927 if (xtmp < 0) xtmp = 0;
928 ytmp = getShort(base2 + i * 2);
929 if (ytmp < 0) ytmp = 0;
930 x[i] = left + xtmp;
931 y[i] = top + ytmp;
932 }
933 if (subPixelResolution)
934 {
935 xf = new float[n];
936 yf = new float[n];
937 base1 = COORDINATES + 4 * n;
938 base2 = base1 + 4 * n;
939 for (int i = 0; i < n; i++)
940 {
941 xf[i] = getFloat(base1 + i * 4);
942 yf[i] = getFloat(base2 + i * 4);
943 }
944 }
945 if (type == point)
946 {
947
948 if (subPixelResolution)
949 {
951 }
952 else
954 if (version >= 226)
955 {
956
957 roi.strokeWidth = getShort(STROKE_WIDTH);
958 }
959
960
961
962
963 roi.type =
ROI.Type.Point;
964 break;
965 }
966 if (type == polygon)
967 roi.type =
ROI.Type.Polygon;
968 else if (type == freehand)
969 {
970 roi.type =
ROI.Type.Freeform;
971 if (subtype == ELLIPSE || subtype == ROTATED_RECT)
972 {
973 throw new NotSupportedException("ROI type not supported.");
974
975
976
977
978
979
980
981
982
983
984
985
986 }
987 }
988 else if (type == traced)
989 roi.type =
ROI.Type.Polyline;
990 else if (type == polyline)
991 roi.type =
ROI.Type.Polyline;
992 else if (type == freeline)
993 roi.type =
ROI.Type.Polyline;
994 else if (type == angle)
995 roi.type =
ROI.Type.Point;
996 else
997 roi.type =
ROI.Type.Freeform;
998 if (subPixelResolution)
999 {
1001
1002
1003 }
1004 else
1006 break;
1007 default:
1008 throw new IOException("Unrecognized ROI type: " + type);
1009 }
1010 if (roi == null)
1011 return null;
1012 roi.roiName = getRoiName();
1013
1014
1015 if (version >= 218)
1016 {
1017 getStrokeWidthAndColor(roi, hdr2Offset, scaleStrokeWidth);
1018
1019
1020
1021
1022
1023
1024
1025 }
1026
1027 if (version >= 218 && subtype == TEXT)
1028 {
1029 getTextRoi(roi, version);
1030 roi.type =
ROI.Type.Label;
1031 }
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051 if (version >= 228 && group > 0)
1052 roi.serie = group;
1053
1054 roi.coord.Z = position;
1055 if (channel > 0 || slice > 0 || frame > 0)
1056 roi.coord = new AForge.ZCT(slice - 1, channel - 1, frame - 1);
1057
1058
1059
1060 if (!roi.subPixel)
1061 {
1062 for (int i = 0; i < roi.PointsD.Count; i++)
1063 {
1065 roi.PointsD[i] = pd;
1067 }
1068 }
1069 if (roi.type ==
ROI.Type.Polygon || roi.type ==
ROI.Type.Freeform)
1070 roi.closed = true;
1071 return roi;
1072 }
PointD ToStageSpace(PointD p)
static ROI CreateRectangle(ZCT coord, double x, double y, double w, double h)
static ROI CreateEllipse(ZCT coord, double x, double y, double w, double h)
void AddPoints(PointD[] p)
static ROI CreateLine(ZCT coord, PointD x1, PointD x2)