• 8258阅读
  • 3回复

[转keisuo整理][备份]实现从RGBA32格式的内存数据中初始化一个QImage [复制链接]

上一主题 下一主题
离线keisuo
 

只看楼主 倒序阅读 楼主  发表于: 2007-05-21
— 本帖被 XChinux 执行加亮操作(2007-05-28) —
[转keisuo整理][备份]实现从RGBA32格式的内存数据中初始化一个QImage

    很多人都为如何将内存中某一个格式的数据如何转换成为图片数据显示到屏幕上犯愁,因为

这是实现处理视频的一个关键部分,我曾经也是,所以深知其不容易,如今,我这里问题已经解

决,所以将解决方法备份与此,仅供参考。
这里提供处理两种数据格式的方法,一种是处理RGB24格式,另一种是RGBA32格式;
说明:
内存中数据保存在pv_frame指针指向的内存空间中;
图象宽度为v_width, the height of it is v_height;(高度是v_height);下面展示方法调用


RGB24:
/**
* lsosa.BIT
*/

int i;
int r, g, b;
QRgb *point;
uchar *bit;
QImage *pVideoImage = new QImage(width, height, 32);
setWFlags(getWFlags() | Qt::WRepaintNoErase);
// these codes should be optimized in future;
// high cpu taked here;
i = 0;
bit = (uchar *)(_frame);
for(int y = 0; y < v_height; y ++){
  for ( int x = 0; x < v_width; x ++ ){
      r = (int)bit;
      g = (int)bit[i+1];
      b = (int)bit[i+2];
      point = (QRgb *)pVideoImage->scanLine(y) + x;
      *point = qRgb(r, g, b);
      i += 3;
  }
}
bitBlt(this, 0, 0, pVideoImage);

the details is here:
http://www.qtcn.org/bbs/read.php?tid=3648&page=e&fpage=5
//////////
1。关于摄像头捕捉图像2
我做的不知道是不是和obrire的一样,但我想摄像头数据截取不分应该是差不多的,
源代码我是不能说的,因为像obrire说的涉及到商业.
基本流程是这样的:先调用系统函数open(dev,O_RDWR);然后开辟共享内存adrr=mmap();adrr是内

存首地址;
再调用ioctl (dev, VIDIOCMCAPTURE, &vid_mmap);ioctl (dev, VIDIOCSYNC,

&vid_mmap.frame);得到图像;
然后再操作adrr就行了;
注意:没用每用完一次mmap()要记得把他销毁munmap(adrr, size);不然它会从新开辟另一块内存.

直到系统内存
被用完.
显示的时候建议先把图像数据拷贝到自己开辟的内存里再对数据进行处理,显示\压缩什么的随你;
显示我的思想方法是,先创建一个Image;然后把数据放到Image里;最后painter出来;
2。skyly2222,你能不能把最后一步images(),这个参数,我设置不好..,显示效果烂的很..
我只需要几行代码,就是qt部分,其他部分,我已经做完了。
3。你能用的是
QImage ( uchar * yourdata, int w, int h, int depth, QRgb * colortable, int numColors,

Endian bitOrder );
这个函数吧?
这个函数我试过,不行,因为colortable设置不好会倒置象素放大或缩小造成图像混乱;
我是这样解决的.
QRgb rgb;
QPainter *paint=new QPainter;
i=0;
if(bm.create(width,height,32,0,QImage::IgnoreEndian))
{        for (x = 0; x < height ; x++) {
          for (y = 0; y <width; y++) {
          r=(int)bit[i+2];
          g=(int)bit[i+1];
          b=(int)bit;
      uint *pp = (uint *)bm.scanLine(x) + y;
        *pp = qRgb(r,g,b);
          i=i+3;
                          }
                    }

}

看得懂的就好,看不懂的我也没办法了.
/////////
http://www.qtcn.org/bbs/read.php?tid=4990&page=e&fpage=1
/////////
还是摄像头问题,能显示但没标题栏,无法控制它
部分源码用的如下
paint=new QPainter(this);
paint->begin(this);

v4l_open("/dev/video0",&device);
unsigned char *data = GrabData();

int x,y;
int i=0;
QImage img;
QRgb *point;
int r,g,b;

if(img.create(480,320,32,0,QImage::IgnoreEndian))
{
for(x=0;x<320;x++)
{
for(y=0;y<480;y++)
{
r=(int)data[i+2];
g=(int)data[i+1];
b=(int)data;
point = (QRgb *) img.scanLine(x)+y;
*point = qRgb(r,g,b);
i+=3;
}
}
}
paint->drawImage(10,10,img);
    我现在根据上面给出的摄像头的一段程序,自己把它写全,已能在板子上显示了,但是那个

图像没含最大化、最小化、关闭按钮的标题栏,请问能把它画在label或是其他qt的类上吗?怎么

画呢,我还想加一个按钮来关闭端口。谢谢!
答:创建个widget。把这段代码写在它的paintEvent里应该就可以了吧
////////

RGBA32:
/**
* lsosa.BIT
*/
QImage *pv_images;
if ( pv_images == NULL ){
  QImage pv_images = new QImage((uchar *)pv_frame, \
      v_width, v_height, 32, NULL, 0, QImage::LittleEndian);
  if ( pv_images == NULL ){
      return -1;
  }
}

all is this...

///////////////////
lsosa 2006-12-14 09:35
这里在补充一种方法,你可以使用QImage 的loadFromData方法从一段内存数据中加载图像,例如


QImage *pf_video_images = new QImage();
pf_video_images->loadFromData(pf_videobuffer, frame_size);
如此应该也可以的;
代码是凭感觉写出来的,为经过测试哦。。。

离线keisuo

只看该作者 1楼 发表于: 2007-05-28
非常有用,如果是其他格式可以用loadfromdata
离线keisuo

只看该作者 2楼 发表于: 2007-05-30
如果 loadfromdata()出错,大多数情况是第三个参数图象格式不对
离线aaniao999

只看该作者 3楼 发表于: 2007-05-31
我就郁闷了,想玩这个没办法玩,我家设想头插上去,就找得到audio,................
快速回复
限100 字节
 
上一个 下一个