Take a Image
HAL Code Example
Taking a picture first requires opening the device with gxi_open_device
, then calling gxi_get_image
to get the image, and finally calling gxi_save_image_as_png
to save the image in the buffer. After that, call gxi_close_device
to close the device.
Of course, in addition to gxi_get_image
to save the image data in the buffer and return Resulf<()>
, there are also two functions gxi_get_image_as_raw
and gxi_get_image_as_bytes
that can return the acquired image data. The former returns Result<&[u8]>
, and the latter returns Result<Vec<u8>>
.
use gxci::hal::device::*; use gxci::hal::base::*; use gxci::utils::debug::print_device_info; fn main()->Result<()> { gxci_init_default()?; let device_num = gxi_count_devices( 1000)?; println!("Device number: {}", device_num); let base_info = gxi_list_devices()?; for device in &base_info { print_device_info(&device); } gxi_open_device()?; gxi_get_image()?; gxi_save_image_as_png("test.png")?; gxi_close_device()?; gxci_close()?; Ok(()) }
HAL Attention
- Of course, you can also take the lazy approach and import everything from 'device' at once, 23333
gxi_open_device
defaults to opening the first device insolo
mode. Multiple devices are not yet supportedgxi_get_image
returnsResult<()>
because the image data is saved in the buffer, so this function only saves the image data in the buffer. If you want to get the image data, you can use the two functionsgxi_get_image_as_raw
andgxi_get_image_as_bytes
- The parameter of the
gxi_save_image_as_png
function is the file name to save, and it is saved in the current directory
RAW Code Example
Taking a picture first requires opening the device with gx_open_device_by_index
, then sending the GX_COMMAND_ACQUISITION_START
command to start the acquisition, then calling gx_get_image
to get the image, after the acquisition is successful, calling the opencv
library to convert the image_buffer
to a Mat
object, and finally calling the imwrite
function of the opencv
library to save the image. After that, call gx_send_command
to send the GX_COMMAND_ACQUISITION_STOP
command to stop the acquisition, and finally call gx_close_device
to close the device.
use std::mem::size_of; use std::slice; use opencv::{ imgcodecs, core, }; use gxci::{ raw::{ gx_interface::*, gx_enum::*, gx_struct::*, gx_handle::*, }, utils::{ debug::print_device_info, builder::GXDeviceBaseInfoBuilder, facade::*, }, }; fn main() -> Result<()> { unsafe { let gx = GXInstance::new("C:\\Program Files\\Daheng Imaging\\GalaxySDK\\APIDll\\Win64\\GxIAPI.dll").expect("Failed to load library"); gx.gx_init_lib().expect("Failed to initialize library"); // Update the device list let mut device_num = 0; gx.gx_update_device_list(&mut device_num, 1000) .expect("Failed to update device list"); if device_num > 0 { let mut base_info: Vec<GX_DEVICE_BASE_INFO> = (0..device_num).map(|_| { GXDeviceBaseInfoBuilder::new().build() }).collect(); let mut size = (device_num as usize) * size_of::<GX_DEVICE_BASE_INFO>(); let status = gx .gx_get_all_device_base_info(base_info.as_mut_ptr(), &mut size) .expect("Failed to get all device base info"); if status == 0 { println!( "Device base info retrieved successfully. Number of devices: {}", device_num ); for device in &base_info { print_device_info(&device); } let first_device_sn = std::str::from_utf8(&base_info[0].szSN).unwrap_or(""); let mut device_handle: GX_DEV_HANDLE = std::ptr::null_mut(); let open_status = gx .gx_open_device_by_index(1, &mut device_handle) .expect("Failed to open device with index"); if open_status == 0 { println!( "Successfully opened device index 1 with SN: {}", first_device_sn.trim_end_matches(char::from(0)) ); gx.gx_send_command(device_handle, GX_FEATURE_ID::GX_COMMAND_ACQUISITION_START) .expect("Failed to send command"); // 这种写法在所有权机制下是错误的,因为image_buffer在返回的时候就已经被释放了 // let frame_data_facade = fetch_frame_data(&gx, device_handle); // let mut frame_data = convert_to_frame_data(&frame_data_facade.unwrap()); // 这种写法是正确的,因为image_buffer被返回到了当前作用域 #[allow(unused_variables)] let (frame_data_facade, image_buffer) = fetch_frame_data(&gx, device_handle).unwrap(); let mut frame_data = convert_to_frame_data(&frame_data_facade); let result = gx.gx_get_image(device_handle, &mut frame_data, 100); match result { Ok(_) => { println!("Image captured successfully."); if frame_data.nStatus == 0 { let data = slice::from_raw_parts(frame_data.pImgBuf as *const u8, (frame_data.nWidth * frame_data.nHeight) as usize); let mat = core::Mat::new_rows_cols_with_data( frame_data.nHeight, frame_data.nWidth, data ).unwrap(); let vec = core::Vector::<i32>::new(); if imgcodecs::imwrite("right.png", &mat, &vec).unwrap() { println!("Image saved successfully."); } else { println!("Failed to save the image."); } } } Err(e) => eprintln!("Failed to capture image: {:?}", e), } gx.gx_send_command(device_handle, GX_FEATURE_ID::GX_COMMAND_ACQUISITION_STOP) .expect("Failed to send command"); // Close the device gx.gx_close_device(device_handle) .expect("Failed to close device"); println!("Device closed.") } else { println!( "Failed to open device with SN: {}", first_device_sn.trim_end_matches(char::from(0)) ); } } else { println!("Failed to retrieve device base info, status: {}", status); } } else { println!("No Devices found."); } gx.gx_close_lib().expect("Failed to close library"); println!("Library closed."); Ok(()) } }
RAW Attention
- Use with caution, it is more comfortable to use
hal
for normal development (mainly because I am lazy to write documents) - The
image_buffer
is released when it is returned, so if it is not returned to the current scope, it will be released in thefacade
function, causing the image data to be directly unavailable in the following text (send the guest without receiving the guest, then the guest dies in a foreign land~)