首页 > 编程知识 正文

像格式转换,像格式

时间:2023-05-06 18:59:43 阅读:261098 作者:1505

读取heic格式图像

读取heic格式图像主要通过第三方库实现,首先创建读取的入口,在前面几期中讲过增加“打开”菜单按钮实现功能。

增加“打开图片”菜单:

QMenu *pMenu = menuBar()->addMenu(QStringLiteral("文件(&F)"));QAction *pOpenFile = new QAction(QStringLiteral("打开图片(&O)"));connect(pOpenFile, &QAction::triggered, this, &heicExample::OpenFile);QAction *pExit = new QAction(QStringLiteral("退出(&Q)"));pMenu->addAction(pOpenFile);pMenu->addAction(pExit);

实现槽函数OpenFile:

void heicExample::OpenFile(){QString fileName = QFileDialog::getOpenFileName(this, tr("open image file"), "./", tr("Image files(*.bmp *.jpg *.pbm *.pgm *.png *.ppm *.xbm *.xpm *.heic);;All files (*.*)")); if (pixItem && fileName != ""){m_graphicsScene->removeItem(pixItem); //将上一个图元从场景中移除,重新添加新的图元delete pixItem;pixItem = NULL;for (int i = 0; i < m_loldrgb.length(); i++){delete m_loldrgb[i];m_loldrgb[i] = NULL;}m_loldrgb.clear();}if(fileName.contains(".heic")){ReadHeif(fileName);}}

读取heic格式文件:

void heicExample::ReadHeif(QString filename){filename = QDir::fromNativeSeparators(filename);Array<ImageId> itemIds;const char* outputFileName = "./abc";// Make an instance of Heif Readerauto *reader = Reader::Create();if (reader->initialize(filename.toLatin1().data()) != ErrorCode::OK)return;// Verify that the file is HEIF format.FileInformation fileInfo;if (reader->getFileInformation(fileInfo) != ErrorCode::OK) {cout << "Unable to get MetaBox! Wrong heif format." << endl;return;}if (!(fileInfo.features & FileFeatureEnum::HasSingleImage ||fileInfo.features & FileFeatureEnum::HasImageCollection)) {cout << "The file don't have images in the Metabox. " << endl;return;}uint64_t memoryBufferSize = 1024 * 1024;ofstream outfile(outputFileName, ofstream::binary);auto *memoryBuffer = new uint8_t[memoryBufferSize];const auto metaBoxFeatures = fileInfo.rootMetaBoxInformation.features;if (metaBoxFeatures & MetaBoxFeatureEnum::HasThumbnails){//reader->getMasterImages(itemIds);//const ImageId masterId = itemIds[0];cout << "The file have Thumbnail." << endl;// Thumbnail references ('thmb') are from the thumbnail image to the master image//reader->getReferencedToItemListByType(masterId, "thmb", itemIds);//const auto thumbnailId = itemIds[0];//if (reader->getItemDataWithDecoderParameters(thumbnailId.get(), memoryBuffer, memoryBufferSize) == ErrorCode::OK)//{// ...decode data and display the image, show master image later//EncodePlay(memoryBuffer, memoryBufferSize);//return;//}}// when the file is iPhone heic.Array<ImageId> gridIds;Grid gridData;if (reader->getItemListByType("grid", gridIds) == ErrorCode::OK &&(fileInfo.features & FileFeatureEnum::HasImageCollection) &&reader->getItem(gridIds[0].get(), gridData) == ErrorCode::OK){//return iphoneHeic(reader, gridData, outputFileName);qDebug("iphone heic");}// The image have collectionsif (fileInfo.features & FileFeatureEnum::HasImageCollection){Array<ImageId> itemIds;reader->getMasterImages(itemIds);// all the image itemsfor (unsigned int i = 0; i < itemIds.size; i++) {const ImageId masterId = itemIds[i];if (reader->getItemDataWithDecoderParameters(masterId.get(), memoryBuffer, memoryBufferSize) == ErrorCode::OK) {DecoderConfiguration decodeConf; // struct containingreader->getDecoderParameterSets(masterId.get(), decodeConf);auto decoSpeInfo = decodeConf.decoderSpecificInfo;for (unsigned int j = 0; j < decoSpeInfo.size; ++j) {auto entry = decoSpeInfo[j];outfile.write((const char *)entry.decSpecInfoData.begin(),entry.decSpecInfoData.size);}outfile.write(reinterpret_cast<const char*>(memoryBuffer), memoryBufferSize);if (i == 0){EncodePlay(memoryBuffer, memoryBufferSize);}}else { cout << "getItemDataWithDecoderParameters error" << endl; }};delete[] memoryBuffer;Reader::Destroy(reader);return;}// The image only have 1 master image.else if (fileInfo.features & FileFeatureEnum::HasSingleImage){Array<ImageId> itemIds;reader->getMasterImages(itemIds);// Find the item ID of the first master imageconst ImageId masterId = itemIds[0];if (reader->getItemDataWithDecoderParameters(masterId.get(), memoryBuffer, memoryBufferSize) == ErrorCode::OK){outfile.write(reinterpret_cast<const char*>(memoryBuffer), memoryBufferSize);cout << "Get the master image" << endl;// ffmpeg// Get HEVC decoder configurationEncodePlay(memoryBuffer, memoryBufferSize);}} cout << "There no image in the file MetaBox! ";Reader::Destroy(reader);return;}

通过EncodePlay函数解析heic格式图像:

void heicExample::EncodePlay(uint8_t * pData, int nDataLength){AVPacket packet;av_init_packet(&packet);packet.data = (uint8_t*)pData;packet.size = nDataLength;packet.pts = (90000 / 25) * m_nFrameCounter++;int ret = -1;ret = avcodec_send_packet(m_pCodecContext, &packet);// Again EAGAIN is not expectedif (ret < 0){return;}while (!ret){ret = avcodec_receive_frame(m_pCodecContext, m_pSrcFrame);if (!ret){//成功解码一帧int w = m_pCodecContext->width;int h = m_pCodecContext->height;if (m_pRGBSwsContext == NULL){m_pRGBSwsContext = sws_getContext(w, h, m_pCodecContext->pix_fmt, w, h, AV_PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);av_image_alloc(m_pFrameRGB->data, m_pFrameRGB->linesize, w, h, AV_PIX_FMT_RGB32, 1);}//转换图像格式,将解压出来的YUV420P的图像转换为RGB的图像sws_scale(m_pRGBSwsContext, (uint8_t const * const *)m_pSrcFrame->data, m_pSrcFrame->linesize, 0, h, m_pFrameRGB->data, m_pFrameRGB->linesize);//把这个RGB数据 用QImage加载QImage tmpImg((uchar *)m_pFrameRGB->data[0], m_pCodecContext->width, m_pCodecContext->height, QImage::Format_RGB32);image = tmpImg.copy();//把图像复制一份 传递给界面显示//emit signal_sendQImage(image);//ui.label->resize(w, h);//QImage img = image.scaled(ui.label->size(), Qt::KeepAspectRatio);//ui.label->setPixmap(QPixmap::fromImage(img));pixItem = new PixItem(QPixmap::fromImage(image));//将该图元对象添加到场景中,并设置此图元在场景中的位置为中心(0,0)m_graphicsScene->addItem(pixItem);pixItem->setPos(0, 0);//保存原来的颜色for (int x = 0; x < image.width(); x++) {for (int y = 0; y < image.height(); y++) {QColor *oldColor = new QColor(image.pixel(x, y));m_loldrgb.append(oldColor);}}av_frame_unref(m_pSrcFrame);}}}

通过ffmpeg解码heic格式,然后转换成RGB32格式,最后通过画布进行展示。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。