55import android .util .Size ;
66
77import androidx .annotation .NonNull ;
8- import androidx .camera .core .CameraSelector ;
98import androidx .camera .core .ImageAnalysis ;
109import androidx .camera .core .Preview ;
1110import androidx .camera .core .resolutionselector .AspectRatioStrategy ;
@@ -45,12 +44,17 @@ public class AdaptiveCameraConfig extends CameraConfig {
4544 */
4645 private static final int IMAGE_QUALITY_480P = 480 ;
4746
47+ /**
48+ * 允许的尺寸偏差比例 15%
49+ */
50+ private static final float ALLOWED_DEVIATION_RATIO = 0.15f ;
51+
4852 private AspectRatioStrategy mAspectRatioStrategy ;
4953
50- private int mPreviewQuality ;
51- private int mAnalysisQuality ;
5254 private Size mPreviewTargetSize ;
5355 private Size mAnalysisTargetSize ;
56+ private int mPreviewQuality ;
57+ private int mAnalysisQuality ;
5458
5559 /**
5660 * 构造
@@ -73,118 +77,91 @@ private void initAdaptiveCameraConfig(Context context) {
7377 LogX .d ("displayMetrics: %dx%d" , width , height );
7478 int processors = Runtime .getRuntime ().availableProcessors ();
7579 LogX .d ("processors: %d" , processors );
76- if (width < height ) {
77- float ratio = height / (float ) width ;
78- if (Math .abs (ratio - CameraScan .ASPECT_RATIO_4_3 ) < Math .abs (ratio - CameraScan .ASPECT_RATIO_16_9 )) {
79- mAspectRatioStrategy = AspectRatioStrategy .RATIO_4_3_FALLBACK_AUTO_STRATEGY ;
80- } else {
81- mAspectRatioStrategy = AspectRatioStrategy .RATIO_16_9_FALLBACK_AUTO_STRATEGY ;
82- }
8380
84- if (width >= IMAGE_QUALITY_1080P ) {
85- mPreviewQuality = IMAGE_QUALITY_1080P ;
86- } else {
87- mPreviewQuality = Math .max (width , IMAGE_QUALITY_720P );
88- }
89- mPreviewTargetSize = new Size (mPreviewQuality , Math .round (mPreviewQuality * ratio ));
90-
91- if (width >= IMAGE_QUALITY_1440P && processors >= 8 ) {
92- mAnalysisQuality = IMAGE_QUALITY_1080P ;
93- } else if (width > IMAGE_QUALITY_720P ) {
94- mAnalysisQuality = IMAGE_QUALITY_720P ;
95- } else {
96- mAnalysisQuality = IMAGE_QUALITY_480P ;
97- }
98- mAnalysisTargetSize = new Size (mAnalysisQuality , Math .round (mAnalysisQuality * ratio ));
81+ int shortSide = Math .min (width , height );
82+ int longSide = Math .max (width , height );
83+ float ratio = longSide / (float ) shortSide ;
84+
85+ if (Math .abs (ratio - CameraScan .ASPECT_RATIO_4_3 ) < Math .abs (ratio - CameraScan .ASPECT_RATIO_16_9 )) {
86+ mAspectRatioStrategy = AspectRatioStrategy .RATIO_4_3_FALLBACK_AUTO_STRATEGY ;
9987 } else {
100- float ratio = width / (float ) height ;
101- if (Math .abs (ratio - CameraScan .ASPECT_RATIO_4_3 ) < Math .abs (ratio - CameraScan .ASPECT_RATIO_16_9 )) {
102- mAspectRatioStrategy = AspectRatioStrategy .RATIO_4_3_FALLBACK_AUTO_STRATEGY ;
103- } else {
104- mAspectRatioStrategy = AspectRatioStrategy .RATIO_16_9_FALLBACK_AUTO_STRATEGY ;
105- }
88+ mAspectRatioStrategy = AspectRatioStrategy .RATIO_16_9_FALLBACK_AUTO_STRATEGY ;
89+ }
10690
107- if (height >= IMAGE_QUALITY_1080P ) {
108- mPreviewQuality = IMAGE_QUALITY_1080P ;
109- } else {
110- mPreviewQuality = Math .max (height , IMAGE_QUALITY_720P );
111- }
112- mPreviewTargetSize = new Size (Math .round (mPreviewQuality * ratio ), mPreviewQuality );
113-
114- if (height >= IMAGE_QUALITY_1440P && processors >= 8 ) {
115- mAnalysisQuality = IMAGE_QUALITY_1080P ;
116- } else if (height > IMAGE_QUALITY_720P ) {
117- mAnalysisQuality = IMAGE_QUALITY_720P ;
118- } else {
119- mAnalysisQuality = IMAGE_QUALITY_480P ;
120- }
121- mAnalysisTargetSize = new Size (Math .round (mAnalysisQuality * ratio ), mAnalysisQuality );
91+ if (shortSide >= IMAGE_QUALITY_1080P ) {
92+ mPreviewQuality = IMAGE_QUALITY_1080P ;
93+ } else {
94+ mPreviewQuality = Math .max (shortSide , IMAGE_QUALITY_720P );
12295 }
123- }
12496
125- @ NonNull
126- @ Override
127- public CameraSelector options (@ NonNull CameraSelector .Builder builder ) {
128- return super .options (builder );
97+ mPreviewTargetSize = new Size (Math .round (mPreviewQuality * ratio ), mPreviewQuality );
98+
99+ if (shortSide >= IMAGE_QUALITY_1440P && processors >= 8 ) {
100+ mAnalysisQuality = IMAGE_QUALITY_1080P ;
101+ } else if (shortSide > IMAGE_QUALITY_720P ) {
102+ mAnalysisQuality = IMAGE_QUALITY_720P ;
103+ } else {
104+ mAnalysisQuality = IMAGE_QUALITY_480P ;
105+ }
106+
107+ mAnalysisTargetSize = new Size (Math .round (mAnalysisQuality * ratio ), mAnalysisQuality );
108+
109+ LogX .d ("Preview target: %s, Analysis target: %s" , mPreviewTargetSize , mAnalysisTargetSize );
129110 }
130111
131112 @ NonNull
132113 @ Override
133114 public Preview options (@ NonNull Preview .Builder builder ) {
134- builder .setResolutionSelector (createPreviewResolutionSelector ( ));
115+ builder .setResolutionSelector (createResolutionSelector ( "Preview" , mPreviewTargetSize , mPreviewQuality ));
135116 return super .options (builder );
136117 }
137118
138119 @ NonNull
139120 @ Override
140121 public ImageAnalysis options (@ NonNull ImageAnalysis .Builder builder ) {
141- builder .setResolutionSelector (createAnalysisResolutionSelector ( ));
122+ builder .setResolutionSelector (createResolutionSelector ( "ImageAnalysis" , mAnalysisTargetSize , mAnalysisQuality ));
142123 return super .options (builder );
143124 }
144125
145126 /**
146- * 创建预览 分辨率选择器 ;根据自适应策略,创建一个合适的 {@link ResolutionSelector}
127+ * 创建分辨率选择器 ;根据自适应策略,创建一个合适的 {@link ResolutionSelector}
147128 *
148129 * @return {@link ResolutionSelector}
149130 */
150- private ResolutionSelector createPreviewResolutionSelector ( ) {
131+ private ResolutionSelector createResolutionSelector ( String tag , Size targetSize , int quality ) {
151132 return new ResolutionSelector .Builder ()
152133 .setAspectRatioStrategy (mAspectRatioStrategy )
153- .setResolutionStrategy (new ResolutionStrategy (mPreviewTargetSize , ResolutionStrategy .FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER ))
134+ .setResolutionStrategy (new ResolutionStrategy (targetSize , ResolutionStrategy .FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER ))
154135 .setResolutionFilter ((supportedSizes , rotationDegrees ) -> {
155- LogX .d ("Preview supportedSizes: " + supportedSizes );
156- List <Size > list = new ArrayList <>();
157- for (Size supportedSize : supportedSizes ) {
158- int size = Math .min (supportedSize .getWidth (), supportedSize .getHeight ());
159- if (size <= mPreviewQuality ) {
160- list .add (supportedSize );
161- }
162- }
163- return list ;
136+ LogX .d ("%s supportedSizes: %s" , tag , supportedSizes );
137+ return filterResolutions (supportedSizes , quality );
164138 })
165139 .build ();
166140 }
167141
168142 /**
169- * 创建分析 分辨率选择器;根据自适应策略,创建一个合适的 {@link ResolutionSelector}
170- *
171- * @return {@link ResolutionSelector}
143+ * 过滤分辨率
172144 */
173- private ResolutionSelector createAnalysisResolutionSelector () {
174- return new ResolutionSelector .Builder ()
175- .setAspectRatioStrategy (mAspectRatioStrategy )
176- .setResolutionStrategy (new ResolutionStrategy (mAnalysisTargetSize , ResolutionStrategy .FALLBACK_RULE_CLOSEST_HIGHER_THEN_LOWER ))
177- .setResolutionFilter ((supportedSizes , rotationDegrees ) -> {
178- LogX .d ("ImageAnalysis supportedSizes: " + supportedSizes );
179- List <Size > list = new ArrayList <>();
180- for (Size supportedSize : supportedSizes ) {
181- int size = Math .min (supportedSize .getWidth (), supportedSize .getHeight ());
182- if (size <= mAnalysisQuality ) {
183- list .add (supportedSize );
184- }
185- }
186- return list ;
187- })
188- .build ();
145+ private List <Size > filterResolutions (List <Size > supportedSizes , int targetQuality ) {
146+ List <Size > list = new ArrayList <>();
147+ int minAcceptable = Math .round (targetQuality * (1 - ALLOWED_DEVIATION_RATIO ));
148+ int maxAcceptable = Math .round (targetQuality * (1 + ALLOWED_DEVIATION_RATIO ));
149+
150+ for (Size supportedSize : supportedSizes ) {
151+ int size = Math .min (supportedSize .getWidth (), supportedSize .getHeight ());
152+ if (size >= minAcceptable && size <= maxAcceptable ) {
153+ list .add (supportedSize );
154+ }
155+ }
156+
157+ LogX .d ("Filtered resolutions for target %d (%d~%d): %s" ,
158+ targetQuality , minAcceptable , maxAcceptable , list );
159+
160+ if (list .isEmpty ()) {
161+ LogX .w ("No suitable resolution found, returning all supported sizes" );
162+ return supportedSizes ;
163+ }
164+
165+ return list ;
189166 }
190167}
0 commit comments