繁体   English   中英

如何在C ++中将Windows位图转换为Actionscript位图

[英]How to convert Windows Bitmap into Actionscript Bitmap in C++

为了避免Windows 8系统上的Actionscript Camera API出现一些(很多)问题,我决定创建一个本机扩展来处理该相机。

现在,相机部件和与AIR Runtime进行通信的所有胶水实际上正在工作,因此单击AIR中的按钮将打开一个新的Windows窗口,该窗口将返回System :: Drawing :: Bitmap。

我的任务是现在

a)创建一个FREBitmapData对象,然后

b)从Windows位图中填写BitmapData。

我想,很多天前应该很容易...因为我对C ++并不十分熟悉,所以我一点都没用。

这是我到目前为止尝试过的:

bmp = form1->bitmap; // bmp is a handle to the System::Drawing::Bitmap returned from the external window
// Lock the bitmap's bits.  
Rectangle rect = Rectangle(0, 0, bmp->Width, bmp->Height);
System::Drawing::Imaging::BitmapData^ bmpData = bmp->LockBits(rect, System::Drawing::Imaging::ImageLockMode::ReadWrite, bmp->PixelFormat);
// Get the address of the first line.
IntPtr ptr = bmpData->Scan0;
// Declare an array to hold the bytes of the bitmap.
// This code is specific to a bitmap with 24 bits per pixels.
int inputLength = Math::Abs(bmpData->Stride) * bmp->Height;
array<Byte>^ input = gcnew array<Byte>(inputLength);
// Copy the RGB values into the array.
System::Runtime::InteropServices::Marshal::Copy(ptr, input, 0, inputLength);
// Unlock the bits.
bmp->UnlockBits(bmpData);
// Create a FREByteArray to hold the data.
// Don't know, if this is necessary
FREObject* outputObject;
FREByteArray* outputBytes = new FREByteArray;
outputBytes->length = inputLength;
outputBytes->bytes = (uint8_t *) &input;
FREAcquireByteArray(outputObject, outputBytes);
// now copy it over
memcpy(outputBytes->bytes, &input, inputLength);
FREReleaseByteArray(outputObject);
// we create a new instance of BitmapData here, 
// as we cannot simply pass it over in the args,
// because we don't know it's correct size at extension creation
FREObject* width;
FRENewObjectFromUint32(bmp->Width, width);
FREObject* height;
FRENewObjectFromUint32(bmp->Height, height);
FREObject* transparent;
FRENewObjectFromBool(uint32_t(0), transparent);
FREObject* fillColor;
FRENewObjectFromUint32(uint32_t(0xFFFFFF), fillColor);
FREObject obs[4] = { width, height, transparent, fillColor };
// we create some Actionscript Intsances here, we want to send back
FREObject* asBmpObj;
FRENewObject("BitmapData", 4, obs, asBmpObj, NULL);
// Now we have our AS bitmap data, copy bytes over
FREBitmapData* asData;
FREAcquireBitmapData(asBmpObj, asData);
// Now what? asData->bits32 won't accept array<Bytes> or any other value I've tried.
return asBmpObj;

基本思想是:

a)找出原始Win Bitmap的大小和位深度(大小由“ Camera”窗口中选择的凸轮分辨率确定)

b)将其字节写入数组。 根据需要转换为32位。 (仍然没有任何想法。)

c)创建相同大小的AS位图。 位深度必须始终为32。

d)复制数组到AS位图。

但是我实在做不到。 有什么建议吗? 谢谢!

我认为以下直接复制无效。

// Copy the RGB values into the array.
System::Runtime::InteropServices::Marshal::Copy(ptr, input, 0, inputLength);

您必须逐像素转换。 我不知道如何将其转换为FREBitmapData。 这是您可以在msdn上关注的示例

我终于想通了:

下面的代码虽然不能处理24to32位转换,但是它实际上在我的应用程序中很好地工作,所以我想,我可能会分享它:

FREObject launch(FREContext ctx, void* funcData, uint32_t argc, FREObject argv[])
{
    System::Drawing::Bitmap^ windowsBitmap;
    SKILLCamControl::CamControlForm^ form1;
    form1 = gcnew SKILLCamControl::CamControlForm();

    DialogResult dr;
    // Show testDialog as a modal dialog and determine if DialogResult = OK.
    dr = form1->ShowDialog();
    if (dr == DialogResult::OK) {

        windowsBitmap = form1->bitmap;
        int bmpW = windowsBitmap->Width;
        int bmpH = windowsBitmap->Height;

        // we create a new instance of BitmapData here, 
        // as we cannot simply pass it over in the args,
        // because we don't know it's correct size at extension creation
        FREObject width;
        FRENewObjectFromUint32( uint32_t(bmpW), &width);

        FREObject height;
        FRENewObjectFromUint32( uint32_t(bmpH), &height);

        FREObject transparent;
        FRENewObjectFromBool( uint32_t(0), &transparent);
        FREObject fillColor;
        FRENewObjectFromUint32( uint32_t(0xFF0000), &fillColor);

        FREObject obs[4] = { width, height, transparent, fillColor };

        FREObject freBitmap;
        FRENewObject((uint8_t *)"flash.display.BitmapData", 4, obs, &freBitmap , NULL);
        FREBitmapData2 freBitmapData;
        FREAcquireBitmapData2(freBitmap, &freBitmapData);

        // is inverted?
        if (&freBitmapData.isInvertedY != (uint32_t*)(0) ) windowsBitmap->RotateFlip(RotateFlipType::RotateNoneFlipY);

        int pixelSize = 4;
        //Rect rect( 0, 0, freBitmap.width, freBitmap.height );
        System::Drawing::Rectangle rect(0, 0, bmpW, bmpH);
        BitmapData^ windowsBitmapData = windowsBitmap->LockBits(rect, ImageLockMode::ReadOnly, PixelFormat::Format32bppArgb);

        for (int y = 0; y < bmpH ; y++)
        {
            //get pixels from each bitmap
            byte* oRow = (byte*)windowsBitmapData->Scan0.ToInt32() + (y * windowsBitmapData->Stride);
            byte* nRow = (byte*)freBitmapData.bits32 + (y * freBitmapData.lineStride32 * 4);

            for (int x = 0; x < bmpW ; x++)
            {
                // set pixels
                nRow[x * pixelSize] = oRow[x * pixelSize]; //B
                nRow[x * pixelSize + 1] = oRow[x * pixelSize + 1]; //G
                nRow[x * pixelSize + 2] = oRow[x * pixelSize + 2]; //R
            }

        }
        // Free resources           
        FREReleaseBitmapData(freBitmap);
        FREInvalidateBitmapDataRect(freBitmap, 0, 0, bmpW, bmpH);

        windowsBitmap->UnlockBits(windowsBitmapData);
        delete windowsBitmapData;
        delete windowsBitmap;

        return freBitmap;

    }
    else if (dr == DialogResult::Cancel)
    {
        return NULL;
    }

    return NULL;
}

我自己不使用C ++,所以这不是一个完整的答案,而只是要考虑的事情...

位图数据是通用原始像素数据。 它应该在不同的软件中可以通过。 除非您实际上是使用标题等创建.BMP文件?

...that will return a System::Drawing::Bitmap ,这是否意味着您具有C ++持有的位图数据(作为未压缩的RGBA原始像素)? 如果是这样,则只需将其放在byteArray中并发送到AS3,或者如果可以将位图复制到Windows剪贴板,则使用AS3从剪贴板中读取到新的AS3位图。

这些可能会帮助您:

  • AS3: 从剪贴板复制图像

  • AS3: 序列化位图 :向下滚动到ByteArray到BitmapData部分(要执行此操作,您必须首先将C ++位图字节存储为文件,然后调用所需的文件,例如tempIMG.dat或myPIc.bin或其他,因为文件扩展名不真的很重要,只是您需要一个可加载的网址)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM