使用 libpng - const 对象保存图像
Saving image with libpng - const object
我有一个管理灰度图像的类。我想用libpng保存它。为此,我想使用如下所示的const
成员函数:
void GrayscaleImage::SavePNG(std::string filename) const
{
// ...
png_bytep* row_pointers = new png_bytep[m_height];
for (int i = 0; i < height_; i++) {
row_pointers[i] = const_cast<png_bytep>(m_data.data()) + i * m_width * sizeof(uint8_t);
}
png_set_rows(png_ptr, info_ptr, row_pointers);
// ...
}
问题是png_set_rows
的第三个参数是非常量参数,所以如果我希望成员函数GrayscaleImage::SavePNG
const
,我必须在某个时候使用 const_cast
。我想知道,这样做安全吗?
>libpng提供了一个API,使其释放row_pointers和它们指向的东西;png_data_freer。 这是读取时的默认值(当前可以调用png_set_rows但调用被忽略)。
你所做的是安全的,只要你不打电话给png_data_freer。 任何写入 API 都不会修改输入数据。
问题存在于png_write_image中,API png_write_png调用也存在,并且存在于png_write_rows中。 它曾经存在于最低级别的 API png_write_row中,但在 libpng 1.5 中得到了修复;这是一个安静的 API 更改,因为它不会更改参数的类型兼容性。 将其更改得更高将导致现有应用程序由于类型错误而无法编译。
你不太可能很快看到变化;在我看来,在libpng 2.0之前,以要求应用程序重写现有代码的方式更改API不太可能发生。
这不安全。 如果没有声明const
png_set_rows()
第三个参数,则无法保证它不会修改输入数据。
您将始终必须处理不声明参数的库,即使它们可以声明参数const
也是如此。 这就是const_cast
存在的原因。 您应该格外小心地使用它。 但从描述来看,png_set_rows()
不太可能修改您的数据。
编辑:这是源代码。 您可以看到它不会修改row_pointers
。 (但它肯定修改了其他两个论点!
void PNGAPI
png_set_rows(png_structp png_ptr, png_infop info_ptr, png_bytepp row_pointers)
{
png_debug1(1, "in %s storage function", "rows");
if (png_ptr == NULL || info_ptr == NULL)
return;
if (info_ptr->row_pointers && (info_ptr->row_pointers != row_pointers))
png_free_data(png_ptr, info_ptr, PNG_FREE_ROWS, 0);
info_ptr->row_pointers = row_pointers;
if (row_pointers)
info_ptr->valid |= PNG_INFO_IDAT;
}
定义中的const
只是说你的实例不应该改变。保存到文件应该不会更改您的实例,所以没关系。当然,png_set_rows
的第三个参数并不const
,因为它被设置了。
在 const 函数中创建、销毁或更改内容并不重要,只要它们不属于您的类即可。您的代码不会更改灰度图像的任何实例。
- Gstreamer:每 5 秒使用多文件墨水保存图像/jpeg
- OpenCV imwrite不会保存图像
- qpixmap qclipboard和保存图像倒置
- 如何从 GIFLIB 保存图像结构中获取 RGB 颜色数据
- 处理openCV后,保存图像要文件
- Haar检测-保存图像的Mat,以便获得并显示前一帧
- 在opencv中使用imwrite保存图像时,会将图像全部写入黑色,但imshow会正确显示
- CImg保存图像会更改值
- 通过WiFi从Android向Windows发送/保存图像时数据过多
- 使用 libpng - const 对象保存图像
- 无法使用OpenCV保存图像
- 如何在c中使用socket编程保存图像数据
- 通用Windows可以动态地绘制图形和保存图像
- 模糊保存图像检测对象使用OpenCV
- Qt抓取小部件和保存图像
- 如何在英特尔RealSense(Visual c++)中保存图像
- 如何从RGBA格式保存图像的缓冲区中创建opencv中的图像
- 如何使用libcurl保存图像
- 需要一些手来渲染、显示和保存图像
- 如何通过http下载和保存图像