1010import numpy as np
1111from .config import logger
1212from .models import TopicInfo
13+ from turbojpeg import TurboJPEG
1314
1415
1516class MessageConverter :
@@ -191,8 +192,38 @@ def _format_image_msg(self, msg: Any, topic_info: Optional[TopicInfo] = None) ->
191192 # For Image messages, we need to encode the data as base64
192193 data_length = getattr (msg , "data_length" , len (msg .data ) if hasattr (msg , "data" ) else 0 )
193194
194- # Convert potentially incompatible encoding
195+ # Check if this is a JPEG-compressed image
195196 encoding = msg .encoding if hasattr (msg , "encoding" ) and msg .encoding else "rgb8"
197+
198+ if encoding .lower () == "jpeg" :
199+ # This is JPEG-compressed data - we need to decode it back to raw pixels
200+ # for Foxglove to display it correctly with the Image schema
201+ if hasattr (msg , "data" ) and data_length > 0 :
202+ jpeg = TurboJPEG ()
203+ # Decode JPEG to BGR array
204+ bgr_array = jpeg .decode (msg .data [:data_length ])
205+
206+ # Update the message properties to reflect raw image
207+ height , width = bgr_array .shape [:2 ]
208+ step = width * 3 # 3 bytes per pixel for BGR
209+
210+ # Convert BGR array back to bytes
211+ image_data_bytes = bgr_array .tobytes ()
212+ image_data = base64 .b64encode (image_data_bytes ).decode ("ascii" )
213+
214+ # Return as raw Image with rgb8 encoding (Foxglove prefers RGB)
215+ return {
216+ "header" : header ,
217+ "height" : height ,
218+ "width" : width ,
219+ "encoding" : "rgb8" , # Foxglove expects rgb8
220+ "is_bigendian" : False ,
221+ "step" : step ,
222+ "data" : image_data
223+ }
224+ else :
225+ image_data = ""
226+
196227 # Foxglove might need rgb8 instead of bgr8
197228 if encoding .lower () == "bgr8" :
198229 # Change the encoding string to rgb8
@@ -492,4 +523,4 @@ def _format_pointcloud2_msg(self, msg: Any, topic_info: Optional[TopicInfo] = No
492523 }
493524 except Exception as e :
494525 logger .error (f"Error formatting PointCloud2: { e } " )
495- return self ._lcm_to_dict (msg ) # Fallback to generic conversion
526+ return self ._lcm_to_dict (msg ) # Fallback to generic conversion
0 commit comments