Как преобразовать растровое изображение Windows в растровое изображение Actionscript в Stack Overflow

обойти некоторые (многие) проблемы с API-интерфейсом Camera Actions в системах Windows 8,
Я решил создать собственное расширение для работы с камерой.

Прямо сейчас часть камеры и весь клей для связи с AIR Runtime фактически работают, поэтому нажатие на кнопку в AIR откроет новое окно Windows, которое вернет System :: Drawing :: Bitmap.

Моя задача была бы сейчас

а) создать объект FREBitmapData и

б) Заполнить BitmapData из Windows Bitmap.

Должно быть, это было легко, подумал я много дней назад … Поскольку я не очень хорошо знаком с 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;

Основная идея была:

а) выяснить размер и битовую глубину оригинального Win Bitmap (размер определяется разрешением камеры, выбранным в окне камеры)

б) записать его байты в массив. Преобразовать в 32 бит при необходимости. (Все еще отсутствует какая-либо идея.)

в) создать AS Bitmap того же размера. Битовая глубина всегда должна быть 32.

d) скопировать массив в AS Bitmap.

Но я просто не могу этого достичь.
Любой совет? Спасибо!

2

Решение

Я не думаю, что следующая прямая копия будет работать.

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

Вы должны конвертировать пиксель за пикселем. Я не знаю, как преобразовать его в FREBitmapData. Вот примеры, вы можете следовать на MSDN

2

Другие решения

Я наконец-то понял:

приведенный ниже код не имеет отношения к преобразованию 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;
}
2

Я сам не пользуюсь C ++, так что это не полный ответ, а просто кое-что для рассмотрения …

Растровые данные — это универсальные необработанные данные пикселей. Это должно быть проходимо в разных программах. Если вы на самом деле не создаете .BMP файлы с заголовком и т.д ??

...that will return a System::Drawing::Bitmap Означает ли это, что у вас есть растровые данные, хранящиеся в C ++ (как необработанные несжатые пиксели RGBA)? Если это так, то просто поместите это в byteArray и отправьте в AS3 или, если вы можете скопировать это растровое изображение в буфер обмена Windows, затем используйте AS3 для чтения из буфера обмена в новое растровое изображение AS3.

это может помочь вам:

1