77import java .util .HashMap ;
88import java .util .List ;
99import java .util .Map ;
10+ import java .util .stream .Collectors ;
1011
1112public class IdealFaceFeatureUtil {
1213
1314 private static final Map <String , Integer > featureIndexMap = new HashMap <>();
1415 private static final List <FeatureInfo > featureInfoList = new ArrayList <>();
16+ private static final Map <String , Map <Integer , FeatureInfo >> categoryIdMap = new HashMap <>();
1517
1618 static {
1719 // 얼굴형
1820 int index = 0 ;
21+ Map <Integer , FeatureInfo > faceShapeMap = new HashMap <>();
1922 for (FaceShape value : FaceShape .values ()) {
2023 featureIndexMap .put (value .name (), index );
21- featureInfoList .add (new FeatureInfo ("얼굴형" , value .name (), value .getName (), index ));
24+ FeatureInfo info = new FeatureInfo ("FACE_SHAPE" , value .name (), value .getName (), index , value .getId ());
25+ featureInfoList .add (info );
26+ faceShapeMap .put (value .getId (), info );
2227 index ++;
2328 }
29+ categoryIdMap .put ("FACE_SHAPE" , faceShapeMap );
2430
2531 // 눈 타입
32+ Map <Integer , FeatureInfo > eyeTypeMap = new HashMap <>();
2633 for (EyeType value : EyeType .values ()) {
2734 featureIndexMap .put (value .name (), index );
28- featureInfoList .add (new FeatureInfo ("눈 타입" , value .name (), value .getName (), index ));
35+ FeatureInfo info = new FeatureInfo ("EYE_TYPE" , value .name (), value .getName (), index , value .getId ());
36+ featureInfoList .add (info );
37+ eyeTypeMap .put (value .getId (), info );
2938 index ++;
3039 }
40+ categoryIdMap .put ("EYE_TYPE" , eyeTypeMap );
3141
3242 // 눈 크기
43+ Map <Integer , FeatureInfo > eyeSizeMap = new HashMap <>();
3344 for (EyeSize value : EyeSize .values ()) {
3445 featureIndexMap .put (value .name (), index );
35- featureInfoList .add (new FeatureInfo ("눈 크기" , value .name (), value .getName (), index ));
46+ FeatureInfo info = new FeatureInfo ("EYE_SIZE" , value .name (), value .getName (), index , value .getId ());
47+ featureInfoList .add (info );
48+ eyeSizeMap .put (value .getId (), info );
3649 index ++;
3750 }
51+ categoryIdMap .put ("EYE_SIZE" , eyeSizeMap );
3852
3953 // 입술 모양
54+ Map <Integer , FeatureInfo > lipShapeMap = new HashMap <>();
4055 for (LipShape value : LipShape .values ()) {
4156 featureIndexMap .put (value .name (), index );
42- featureInfoList .add (new FeatureInfo ("입술 모양" , value .name (), value .getName (), index ));
57+ FeatureInfo info = new FeatureInfo ("LIP_SHAPE" , value .name (), value .getName (), index , value .getId ());
58+ featureInfoList .add (info );
59+ lipShapeMap .put (value .getId (), info );
4360 index ++;
4461 }
62+ categoryIdMap .put ("LIP_SHAPE" , lipShapeMap );
4563
4664 // 코 모양
65+ Map <Integer , FeatureInfo > noseShapeMap = new HashMap <>();
4766 for (NoseShape value : NoseShape .values ()) {
4867 featureIndexMap .put (value .name (), index );
49- featureInfoList .add (new FeatureInfo ("코 모양" , value .name (), value .getName (), index ));
68+ FeatureInfo info = new FeatureInfo ("NOSE_SHAPE" , value .name (), value .getName (), index , value .getId ());
69+ featureInfoList .add (info );
70+ noseShapeMap .put (value .getId (), info );
5071 index ++;
5172 }
73+ categoryIdMap .put ("NOSE_SHAPE" , noseShapeMap );
5274
5375 // 턱 모양
76+ Map <Integer , FeatureInfo > jawShapeMap = new HashMap <>();
5477 for (JawShape value : JawShape .values ()) {
5578 featureIndexMap .put (value .name (), index );
56- featureInfoList .add (new FeatureInfo ("턱 모양" , value .name (), value .getName (), index ));
79+ FeatureInfo info = new FeatureInfo ("JAW_SHAPE" , value .name (), value .getName (), index , value .getId ());
80+ featureInfoList .add (info );
81+ jawShapeMap .put (value .getId (), info );
5782 index ++;
5883 }
84+ categoryIdMap .put ("JAW_SHAPE" , jawShapeMap );
5985
6086 // 이마
87+ Map <Integer , FeatureInfo > foreheadMap = new HashMap <>();
6188 for (ForeHead value : ForeHead .values ()) {
6289 featureIndexMap .put (value .name (), index );
63- featureInfoList .add (new FeatureInfo ("이마" , value .name (), value .getName (), index ));
90+ FeatureInfo info = new FeatureInfo ("FOREHEAD" , value .name (), value .getName (), index , value .getId ());
91+ featureInfoList .add (info );
92+ foreheadMap .put (value .getId (), info );
6493 index ++;
6594 }
95+ categoryIdMap .put ("FOREHEAD" , foreheadMap );
6696
6797 // 피부 톤
98+ Map <Integer , FeatureInfo > skinToneMap = new HashMap <>();
6899 for (SkinTone value : SkinTone .values ()) {
69100 featureIndexMap .put (value .name (), index );
70- featureInfoList .add (new FeatureInfo ("피부 톤" , value .name (), value .getName (), index ));
101+ FeatureInfo info = new FeatureInfo ("SKIN_TONE" , value .name (), value .getName (), index , value .getId ());
102+ featureInfoList .add (info );
103+ skinToneMap .put (value .getId (), info );
71104 index ++;
72105 }
106+ categoryIdMap .put ("SKIN_TONE" , skinToneMap );
73107
74108 // 수염
109+ Map <Integer , FeatureInfo > beardMap = new HashMap <>();
75110 for (Beard value : Beard .values ()) {
76111 featureIndexMap .put (value .name (), index );
77- featureInfoList .add (new FeatureInfo ("수염" , value .name (), value .getName (), index ));
112+ FeatureInfo info = new FeatureInfo ("BEARD" , value .name (), value .getName (), index , value .getId ());
113+ featureInfoList .add (info );
114+ beardMap .put (value .getId (), info );
78115 index ++;
79116 }
117+ categoryIdMap .put ("BEARD" , beardMap );
80118
81119 // 안경
120+ Map <Integer , FeatureInfo > glassMap = new HashMap <>();
82121 for (Glass value : Glass .values ()) {
83122 featureIndexMap .put (value .name (), index );
84- featureInfoList .add (new FeatureInfo ("안경" , value .name (), value .getName (), index ));
123+ FeatureInfo info = new FeatureInfo ("GLASS" , value .name (), value .getName (), index , value .getId ());
124+ featureInfoList .add (info );
125+ glassMap .put (value .getId (), info );
85126 index ++;
86127 }
128+ categoryIdMap .put ("GLASS" , glassMap );
87129
88130 // 동물상
131+ Map <Integer , FeatureInfo > animalLookMap = new HashMap <>();
89132 for (AnimalLook value : AnimalLook .values ()) {
90133 featureIndexMap .put (value .name (), index );
91- featureInfoList .add (new FeatureInfo ("동물상" , value .name (), value .getName (), index ));
134+ FeatureInfo info = new FeatureInfo ("ANIMAL_LOOK" , value .name (), value .getName (), index , value .getId ());
135+ featureInfoList .add (info );
136+ animalLookMap .put (value .getId (), info );
92137 index ++;
93138 }
139+ categoryIdMap .put ("ANIMAL_LOOK" , animalLookMap );
94140
95141 // 나이
142+ Map <Integer , FeatureInfo > ageMap = new HashMap <>();
96143 for (Age value : Age .values ()) {
97144 featureIndexMap .put (value .name (), index );
98- featureInfoList .add (new FeatureInfo ("나이" , value .name (), value .getName (), index ));
145+ FeatureInfo info = new FeatureInfo ("AGE" , value .name (), value .getName (), index , value .getId ());
146+ featureInfoList .add (info );
147+ ageMap .put (value .getId (), info );
99148 index ++;
100149 }
150+ categoryIdMap .put ("AGE" , ageMap );
101151 }
102152
103153 public static Integer getFeatureIndex (String featureName ) {
@@ -110,20 +160,88 @@ public static List<FeatureInfo> getAllFeatureInfos() {
110160
111161 public static List <FeatureInfo > getFeatureInfosFromBitmask (BigInteger bitmask ) {
112162 List <FeatureInfo > selectedFeatures = new ArrayList <>();
113-
163+
114164 for (FeatureInfo featureInfo : featureInfoList ) {
115165 if (bitmask .testBit (featureInfo .index ())) {
116166 selectedFeatures .add (featureInfo );
117167 }
118168 }
119-
169+
120170 return selectedFeatures ;
121171 }
122-
172+
173+ public static BigInteger convertIdsToBitmask (Map <String , List <Integer >> categoryIds ) {
174+ BigInteger bitmask = BigInteger .ZERO ;
175+
176+ for (Map .Entry <String , List <Integer >> entry : categoryIds .entrySet ()) {
177+ String category = entry .getKey ();
178+ List <Integer > ids = entry .getValue ();
179+ Map <Integer , FeatureInfo > featureMap = categoryIdMap .get (category );
180+
181+ if (featureMap != null ) {
182+ for (Integer id : ids ) {
183+ FeatureInfo info = featureMap .get (id );
184+ if (info != null ) {
185+ bitmask = bitmask .setBit (info .index ());
186+ }
187+ }
188+ }
189+ }
190+
191+ return bitmask ;
192+ }
193+
194+ public static Map <String , List <Integer >> convertBitmaskToIds (BigInteger bitmask ) {
195+ Map <String , List <Integer >> result = new HashMap <>();
196+
197+ for (FeatureInfo info : featureInfoList ) {
198+ if (bitmask .testBit (info .index ())) {
199+ result .computeIfAbsent (info .category (), k -> new ArrayList <>())
200+ .add (info .featureId ());
201+ }
202+ }
203+
204+ return result ;
205+ }
206+
207+ public static List <FeatureInfo > getFeatureInfosByIds (Map <String , List <Integer >> categoryIds ) {
208+ List <FeatureInfo > result = new ArrayList <>();
209+
210+ for (Map .Entry <String , List <Integer >> entry : categoryIds .entrySet ()) {
211+ String category = entry .getKey ();
212+ List <Integer > ids = entry .getValue ();
213+ Map <Integer , FeatureInfo > featureMap = categoryIdMap .get (category );
214+
215+ if (featureMap != null ) {
216+ for (Integer id : ids ) {
217+ FeatureInfo info = featureMap .get (id );
218+ if (info != null ) {
219+ result .add (info );
220+ }
221+ }
222+ }
223+ }
224+
225+ return result ;
226+ }
227+
228+ public static FeatureInfo getFeatureInfoByNameAndCategory (String name , String category ) {
229+ return featureInfoList .stream ()
230+ .filter (info -> info .name ().equals (name ) && info .category ().equals (category ))
231+ .findFirst ()
232+ .orElse (null );
233+ }
234+
123235 public record FeatureInfo (
124236 String category ,
125237 String code ,
126238 String name ,
127- int index
128- ) {}
239+ int index ,
240+ int featureId
241+ ) {
242+ // 기존 코드와의 호환성을 위한 생성자
243+ public FeatureInfo (String category , String code , String name , int index ) {
244+ this (category , code , name , index , 0 );
245+ }
246+ }
129247}
0 commit comments