Loading...
Searching...
No Matches
BitmapRegionDecoderExample.kt
Go to the documentation of this file.
1import com.navigine.idl.java.BitmapRegionDecoder
2import com.navigine.idl.java.Image
3
4import kotlinx.coroutines.delay
5import kotlinx.coroutines.runBlocking
6
7/**
8 * BitmapRegionDecoder usage example for Kotlin
9 * Demonstrates working with bitmap region decoding, image processing, and rectangle operations
10 */
11class BitmapRegionDecoderExample {
12 private var decoder: BitmapRegionDecoder? = null
13 private var imageData: ByteArray? = null
14
15 init {
16 loadSampleImageData()
17 }
18
19 /**
20 * Load sample image data for demonstration
21 */
22 private fun loadSampleImageData() {
23 // Simulate loading image data (in real app, this would be from file or network)
24 imageData = byteArrayOf(
25 0x89.toByte(), 0x50.toByte(), 0x4E.toByte(), 0x47.toByte(),
26 0x0D.toByte(), 0x0A.toByte(), 0x1A.toByte(), 0x0A.toByte() // PNG header
27 // ... more image data would be here
28 )
29 println("Sample image data loaded (${imageData!!.size} bytes)")
30 }
31
32 /**
33 * Demonstrate BitmapRegionDecoder methods
34 */
35 fun demonstrateBitmapRegionDecoderMethods() {
36 if (imageData == null) {
37 System.err.println("No image data available")
38 return
39 }
40
41 // [kotlin_BitmapRegionDecoder_newInstance]
42 // Create new instance of BitmapRegionDecoder
43 decoder = BitmapRegionDecoder.newInstance(imageData!!)
44 println("Created BitmapRegionDecoder instance")
45 // [kotlin_BitmapRegionDecoder_newInstance]
46
47 // [kotlin_BitmapRegionDecoder_newInstanceFromImage]
48 // When you already have an Image (e.g. from SDK), create decoder without passing raw bytes again
49 val imageForDecoder: Image? = null // set from your pipeline when available
50 val decoderFromImage = BitmapRegionDecoder.newInstanceFromImage(imageForDecoder)
51 println("Decoder from Image: ${decoderFromImage != null}")
52 // [kotlin_BitmapRegionDecoder_newInstanceFromImage]
53
54 // [kotlin_BitmapRegionDecoder_getWidth]
55 val sourceWidth = decoder!!.width
56 println("Source image width: $sourceWidth")
57 // [kotlin_BitmapRegionDecoder_getWidth]
58
59 // [kotlin_BitmapRegionDecoder_getHeight]
60 val sourceHeight = decoder!!.height
61 println("Source image height: $sourceHeight")
62 // [kotlin_BitmapRegionDecoder_getHeight]
63
64 // Demonstrate rectangle creation and usage
65 demonstrateRectangleUsage()
66
67 // Demonstrate region decoding
68 demonstrateRegionDecoding()
69
70 // Demonstrate different sample sizes
71 demonstrateSampleSizes()
72
73 // Demonstrate multiple regions
74 demonstrateMultipleRegions()
75 }
76
77 /**
78 * Demonstrate Rectangle usage
79 */
80 fun demonstrateRectangleUsage() {
81 // [kotlin_Rectangle_constructor]
82 // Create rectangle with x, y, width, height
83 val rect1 = Rectangle(10, 20, 100, 150)
84 println("Created rectangle: x=${rect1.x}, y=${rect1.y}, width=${rect1.width}, height=${rect1.height}")
85 // [kotlin_Rectangle_constructor]
86
87 // [kotlin_Rectangle_getX]
88 // Get X coordinate
89 val x = rect1.x
90 println("Rectangle X coordinate: $x")
91 // [kotlin_Rectangle_getX]
92
93 // [kotlin_Rectangle_getY]
94 // Get Y coordinate
95 val y = rect1.y
96 println("Rectangle Y coordinate: $y")
97 // [kotlin_Rectangle_getY]
98
99 // [kotlin_Rectangle_getWidth]
100 // Get width
101 val width = rect1.width
102 println("Rectangle width: $width")
103 // [kotlin_Rectangle_getWidth]
104
105 // [kotlin_Rectangle_getHeight]
106 // Get height
107 val height = rect1.height
108 println("Rectangle height: $height")
109 // [kotlin_Rectangle_getHeight]
110
111 // Create different rectangles for different use cases
112 val fullImage = Rectangle(0, 0, 1024, 768)
113 val topLeft = Rectangle(0, 0, 512, 384)
114 val center = Rectangle(256, 192, 512, 384)
115 val bottomRight = Rectangle(512, 384, 512, 384)
116
117 println("Created different rectangles for different regions")
118 }
119
120 /**
121 * Demonstrate region decoding
122 */
123 fun demonstrateRegionDecoding() {
124 val decoder = decoder ?: run {
125 System.err.println("Decoder not initialized")
126 return
127 }
128
129 // Create a sample rectangle
130 val sampleRect = Rectangle(50, 50, 200, 200)
131
132 // [kotlin_BitmapRegionDecoder_decodeRegion]
133 // Decode region with sample size 1 (full resolution)
134 val decodedImage = decoder.decodeRegion(sampleRect, 1)
135 println("Decoded region: ${sampleRect.width}x${sampleRect.height} at sample size 1")
136 // [kotlin_BitmapRegionDecoder_decodeRegion]
137
138 // Demonstrate the decoded image
139 demonstrateDecodedImage(decodedImage, "Sample Region")
140 }
141
142 /**
143 * Demonstrate different sample sizes
144 */
145 fun demonstrateSampleSizes() {
146 val decoder = decoder ?: return
147
148 val testRect = Rectangle(0, 0, 400, 300)
149
150 // Decode with different sample sizes
151 val sampleSizes = listOf(1.0f, 2.0f, 4.0f, 8.0f)
152
153 for (sampleSize in sampleSizes) {
154 // [kotlin_BitmapRegionDecoder_decodeRegion_sampleSize]
155 // Decode region with specific sample size
156 val decodedImage = decoder.decodeRegion(testRect, sampleSize)
157 println("Decoded region with sample size $sampleSize: ${(testRect.width / sampleSize).toInt()}x${(testRect.height / sampleSize).toInt()}")
158 // [kotlin_BitmapRegionDecoder_decodeRegion_sampleSize]
159
160 demonstrateDecodedImage(decodedImage, "Sample Size $sampleSize")
161 }
162 }
163
164 /**
165 * Demonstrate multiple regions
166 */
167 fun demonstrateMultipleRegions() {
168 val decoder = decoder ?: return
169
170 // Define multiple regions to decode
171 val regions = listOf(
172 Rectangle(0, 0, 256, 256), // Top-left quadrant
173 Rectangle(256, 0, 256, 256), // Top-right quadrant
174 Rectangle(0, 256, 256, 256), // Bottom-left quadrant
175 Rectangle(256, 256, 256, 256) // Bottom-right quadrant
176 )
177
178 println("=== Decoding Multiple Regions ===")
179 for (i in regions.indices) {
180 val region = regions[i]
181
182 // [kotlin_BitmapRegionDecoder_decodeRegion_multiple]
183 // Decode multiple regions
184 val decodedImage = decoder.decodeRegion(region, 1)
185 println("Region ${i + 1}: ${region.width}x${region.height} at (${region.x}, ${region.y})")
186 // [kotlin_BitmapRegionDecoder_decodeRegion_multiple]
187
188 demonstrateDecodedImage(decodedImage, "Region ${i + 1}")
189 }
190 }
191
192 /**
193 * Demonstrate decoded image usage
194 */
195 fun demonstrateDecodedImage(image: ImageWrapper, description: String) {
196 println("--- $description ---")
197 println("Image dimensions: ${image.width}x${image.height}")
198 println("Image format: ${image.format}")
199 println("Image data size: ${image.data.size} bytes")
200 println("---")
201 }
202
203 /**
204 * Demonstrate advanced bitmap region decoder features
205 */
206 suspend fun demonstrateAdvancedFeatures() {
207 println("=== Advanced BitmapRegionDecoder Features ===")
208
209 if (imageData == null) {
210 return
211 }
212
213 // Create multiple decoders for different images
214 val imageDataList = listOf(
215 imageData!!,
216 byteArrayOf(0xFF.toByte(), 0xD8.toByte(), 0xFF.toByte(), 0xE0.toByte()), // JPEG header
217 byteArrayOf(0x47.toByte(), 0x49.toByte(), 0x46.toByte(), 0x38.toByte()) // GIF header
218 )
219
220 for (i in imageDataList.indices) {
221 try {
222 // [kotlin_BitmapRegionDecoder_newInstance_advanced]
223 // Create decoder for different image types
224 val decoder = BitmapRegionDecoder.newInstance(imageDataList[i])
225 println("Created decoder for image type ${i + 1}")
226 // [kotlin_BitmapRegionDecoder_newInstance_advanced]
227
228 // Test decoding with different regions
229 val testRect = Rectangle(0, 0, 100, 100)
230 val decodedImage = decoder.decodeRegion(testRect, 1)
231 println("Successfully decoded region from image type ${i + 1}")
232
233 } catch (e: Exception) {
234 System.err.println("Failed to decode image type ${i + 1}: ${e.message}")
235 }
236 }
237 }
238
239 /**
240 * Demonstrate error handling
241 */
242 fun demonstrateErrorHandling() {
243 println("=== Error Handling ===")
244
245 // Test with invalid image data
246 val invalidData = byteArrayOf(0x00.toByte(), 0x01.toByte(), 0x02.toByte(), 0x03.toByte())
247
248 try {
249 // [kotlin_BitmapRegionDecoder_newInstance_error]
250 // Create decoder with invalid data
251 val decoder = BitmapRegionDecoder.newInstance(invalidData)
252 println("Created decoder with invalid data")
253 // [kotlin_BitmapRegionDecoder_newInstance_error]
254
255 // Try to decode region
256 val rect = Rectangle(0, 0, 50, 50)
257 val image = decoder.decodeRegion(rect, 1)
258 println("Successfully decoded region from invalid data")
259
260 } catch (e: Exception) {
261 println("Expected error when creating decoder with invalid data: ${e.message}")
262 }
263
264 // Test with invalid rectangle
265 decoder?.let { decoder ->
266 try {
267 val invalidRect = Rectangle(-10, -10, 100, 100)
268 val image = decoder.decodeRegion(invalidRect, 1)
269 println("Successfully decoded region with negative coordinates")
270
271 } catch (e: Exception) {
272 println("Expected error with invalid rectangle: ${e.message}")
273 }
274 }
275 }
276
277 /**
278 * Demonstrate performance optimization
279 */
280 fun demonstratePerformanceOptimization() {
281 println("=== Performance Optimization ===")
282
283 val decoder = decoder ?: return
284
285 // Test different sample sizes for performance
286 val largeRect = Rectangle(0, 0, 800, 600)
287 val sampleSizes = listOf(1.0f, 2.0f, 4.0f, 8.0f, 16.0f)
288
289 for (sampleSize in sampleSizes) {
290 val startTime = System.currentTimeMillis()
291
292 val image = decoder.decodeRegion(largeRect, sampleSize)
293
294 val endTime = System.currentTimeMillis()
295 println("Sample size $sampleSize: ${endTime - startTime}ms, " +
296 "Output size: ${image.width}x${image.height}")
297 }
298 }
299
300 /**
301 * Demonstrate rectangle manipulation
302 */
303 fun demonstrateRectangleManipulation() {
304 println("=== Rectangle Manipulation ===")
305
306 // Create base rectangle
307 val baseRect = Rectangle(100, 100, 200, 150)
308 println("Base rectangle: ${baseRect.x}, ${baseRect.y}, ${baseRect.width}x${baseRect.height}")
309
310 // Create different variations
311 val variations = listOf(
312 Rectangle(baseRect.x, baseRect.y, baseRect.width / 2, baseRect.height), // Half width
313 Rectangle(baseRect.x, baseRect.y, baseRect.width, baseRect.height / 2), // Half height
314 Rectangle(baseRect.x + 50, baseRect.y + 25, baseRect.width - 100, baseRect.height - 50), // Centered smaller
315 Rectangle(0, 0, baseRect.width, baseRect.height) // Top-left aligned
316 )
317
318 for (i in variations.indices) {
319 val rect = variations[i]
320 println("Variation ${i + 1}: ${rect.x}, ${rect.y}, ${rect.width}x${rect.height}")
321 }
322 }
323
324 /**
325 * Main demonstration method
326 */
327 suspend fun runExample() {
328 println("=== BitmapRegionDecoder Example ===")
329
330 demonstrateBitmapRegionDecoderMethods()
331 demonstrateRectangleManipulation()
332 demonstrateAdvancedFeatures()
333 demonstrateErrorHandling()
334 demonstratePerformanceOptimization()
335
336 // Wait a bit for processing
337 delay(2000)
338
339 println("=== Example completed ===")
340 }
341}
342
343/**
344 * Function to run the example
345 */
346fun main() = runBlocking {
347 val example = BitmapRegionDecoderExample()
348 example.runExample()
349}