hjyoo


Dear all,

I'd like to read(decode) pixel values of raw image(.cr2) and modify, and then save(encode) the modified pixel values as same raw image format(.cr2).

Now, I successed to decode the raw image file and get the pixel values by using IWICBitmapFrameDecode::CopyPixels.

After modifying the pixel values, I tried to write the pixel values as IWICBitmapFrameEncode::WritePixels. But it did not work!!

When I tried to above process with *.jpg, it worked!! The function IWICBitmapFrameEncode::WritePixels() returned S_OK!!

But when I tried with *.cr2, it returned '-2003292287'!!

What I'm missed

Could anyone help me please

Thank you.




Re: How to modify the pixel value of RAW image (.cr2) and save(encoding) again ?

Robert A. Wlodarczyk - MSFT


This HRESULT is "WINCODEC_ERR_UNSUPPORTEDOPERATION". This means that the CR2 CODEC that you are using does not support making modifications to the image bits.





Re: How to modify the pixel value of RAW image (.cr2) and save(encoding) again ?

hjyoo

First of all, thank you very much for your answer.

I sill have some questions.

<Question 1>

I had download the codec from Canon site. Is there any other Canon codec that can allow to save as raw image

If not, can I save the pixel values as other image format(jpeg, tiff, etc..) Could you recommand the best way

<Question 2>

I'd like to check what the decoded pixel values mean.

The decoded pixel values of raw image are not yet processed.

If the decoded pixel values are not processed values, I have to know what the pixel values mean exactly because I 'd like to modify the pixel values before the values are changed to low-dynamic-range values(like 0-255).

Also, after modifying, I have to convert this data to low-dynamic-range value(0-255) to rendering at monitor. Where I can find this kinds of information

If the decoded pixel values are already processed values, I'd like to want to know the range of the values.

Thank you.







Re: How to modify the pixel value of RAW image (.cr2) and save(encoding) again ?

Robert A. Wlodarczyk - MSFT

<Question 1>

I had download the codec from Canon site. Is there any other Canon codec that can allow to save as raw image

If not, can I save the pixel values as other image format(jpeg, tiff, etc..) Could you recommand the best way

You can resave the image as a TIFF. Basically you can copy over the frames from the RAW file to the encoder for TIFF. If you take a look at the WICExplorer code, there is an example of how to "transcode" an image from one format to another.

<Question 2>

I'd like to check what the decoded pixel values mean.

The decoded pixel values of raw image are not yet processed.

If the decoded pixel values are not processed values, I have to know what the pixel values mean exactly because I 'd like to modify the pixel values before the values are changed to low-dynamic-range values(like 0-255).

Also, after modifying, I have to convert this data to low-dynamic-range value(0-255) to rendering at monitor. Where I can find this kinds of information

If the decoded pixel values are already processed values, I'd like to want to know the range of the values.

RAW CODECs should implement the IWICDevelopRaw interface. You can QI for this interface and then process the pixels that way.





Re: How to modify the pixel value of RAW image (.cr2) and save(encoding) again ?

hjyoo

ok, thank you.

I will try.^^






Re: How to modify the pixel value of RAW image (.cr2) and save(encoding) again ?

hjyoo

Hello,

First, I have succeeded to resave as *.tiff.

But, the pixel value of *.cr2 from IWICBitmapSource.CopyPixel is 8bit data(0-255), even though the pixel has 2 Byte per each channel.

Don't I get RAW pixel vaue(14bit)






Re: How to modify the pixel value of RAW image (.cr2) and save(encoding) again ?

Robert A. Wlodarczyk - MSFT

Are you doing any format conversion before CopyPixels Can you post a sample of the code that you're using





Re: How to modify the pixel value of RAW image (.cr2) and save(encoding) again ?

hjyoo

Hello,

First of all, I really appreciate your help.^^

I didn't format conversion. Do you means pixel format conversion What shoud I do for that

This is my code. It is really simple. I just used CopyPixel.

The CR2 file use 6 byte per pixel. (2byte per each channel. = 0~65535 for each RGB)

CopyPixel returns the number of (width*height*6) values as Byte type.

So, I'd like to convert 2byte of pbBuffer to integer type from 0 to 65535.

Now,in code, I just do 'static cast' from BYTE to INT.

But the result is very strange.

Every even array of 'tmp' has '0', and every odd array has RGB pixel value from 0 to 255.

I worried about the result means that the CopyPixel function does not returns 16bit pixel value.

How I can get raw pixel values

Also, I'd like to know the vise versa case, from integer(0~65535) to BYTE properly for CR2.

Finally, if I get the 16 bit pixel value, how can I confirm this value is correct or not

Is there any software which shows the raw image, but also represents the 16 bit pixel value at the screen

Thank you.

=========================================================================

Code Block

int main(int argc, CHAR* argv[])
{

//Initialize COM.
CoInitialize(NULL);

////////////////////////////////////////////////////////////////////////////
//part1
//Create a WIC Decoder
////////////////////////////////////////////////////////////////////////////
IWICImagingFactory *piFactory = NULL;
IWICBitmapDecoder *piDecoder = NULL;

//Create the COM imaging factory.
HRESULT hr = CoCreateInstance(
CLSID_WICImagingFactory,
NULL,
CLSCTX_INPROC_SERVER,
IID_IWICImagingFactory,
(LPVOID*)&piFactory);

//Create the decoder.
if (SUCCEEDED(hr))
{
hr = piFactory->CreateDecoderFromFilename(
L"test_raw.cr2",
NULL,
GENERIC_READ,
WICDecodeMetadataCacheOnDemand, //For JPEG lossless decoding/encoding.
&piDecoder);
}

////////////////////////////////////////////////////////////////////////////
//part2
//Create a WIC Encoder
//to encode the new image
////////////////////////////////////////////////////////////////////////////
//Variables used for encoding.
IWICStream *piFileStream = NULL;
IWICBitmapEncoder *piEncoder = NULL;
IWICMetadataBlockWriter *piBlockWriter = NULL;
IWICMetadataBlockReader *piBlockReader = NULL;
PROPVARIANT value;

WICPixelFormatGUID pixelFormat = { 0 };
UINT count = 0;
double dpiX=0, dpiY = 0.0;
UINT width=0, height = 0;

//Initialize PROPVARIANT
PropVariantInit(&value);

// Create a file stream.
if (SUCCEEDED(hr))
{
hr = piFactory->CreateStream(&piFileStream);
}

// Initialize our new file stream.
if (SUCCEEDED(hr))
{
hr = piFileStream->InitializeFromFilename(L"test2.tiff", GENERIC_WRITE);
}

// Create the encoder.
if (SUCCEEDED(hr))
{
hr = piFactory->CreateEncoder(GUID_ContainerFormatTiff, NULL, &piEncoder);
}
// Initialize the encoder
if (SUCCEEDED(hr))
{
hr = piEncoder->Initialize(piFileStream,WICBitmapEncoderNoCache);
}


////////////////////////////////////////////////////////////////////////////
//part3
//Copy Decoded Frame Information
////////////////////////////////////////////////////////////////////////////
if (SUCCEEDED(hr))
{
piDecoder->GetFrameCount(&count);
}

//Process each frame of the image.
for (UINT i=0; i<count && SUCCEEDED(hr); i++)
{
//Frame variables.
IWICBitmapFrameDecode *piFrameDecode = NULL;
IWICBitmapFrameEncode *piFrameEncode = NULL;
IWICMetadataQueryReader *piFrameQReader = NULL;
IWICMetadataQueryWriter *piFrameQWriter = NULL;

//Get and create image frame.
if (SUCCEEDED(hr))
{
hr = piDecoder->GetFrame(i, &piFrameDecode);
}
if (SUCCEEDED(hr))
{
hr = piEncoder->CreateNewFrame(&piFrameEncode, NULL);
}

//Initialize the encoder.
if (SUCCEEDED(hr))
{
hr = piFrameEncode->Initialize(NULL);
}
//Get and set size.
if (SUCCEEDED(hr))
{
piFrameDecode->GetSize(&width, &height);
}
if (SUCCEEDED(hr))
{
hr = piFrameEncode->SetSize(width, height);
}
//Get and set resolution.
if (SUCCEEDED(hr))
{
piFrameDecode->GetResolution(&dpiX, &dpiY);
}
if (SUCCEEDED(hr))
{
hr = piFrameEncode->SetResolution(dpiX, dpiY);
}
//Set pixel format.
if (SUCCEEDED(hr))
{
piFrameDecode->GetPixelFormat(&pixelFormat);
}
if (SUCCEEDED(hr))
{
hr = piFrameEncode->SetPixelFormat(&pixelFormat);
}

////////////////////////////////////////////////////////////////////////////
//part3
//Finalize the Encoded Image
////////////////////////////////////////////////////////////////////////////

// To get cbStride, create IWICBitmapSource, IWICBitmap and IWICBitmapLock.
IWICBitmapSource *piBitmapSource = NULL;
IWICBitmap *piBitmap = NULL;
IWICBitmapLock *piBitmapLock = NULL;
WICRect prc = {0,0,width,height};
UINT cbStride = 0;

piBitmapSource = static_cast<IWICBitmapSource*>(piFrameDecode);
piBitmapSource->GetSize(&width, &height);

hr = piFactory->CreateBitmapFromSource(piBitmapSource, WICBitmapCacheOnLoad, &piBitmap);
hr = piBitmap->Lock(&prc, WICBitmapLockWrite, &piBitmapLock);

// Get Stride!!
// In (*.cr2) case, the function returns 'width * 6', [6 byte / pixel] as cbStride.
// it means each RGB channel has 2 Byte(16bit).
hr = piBitmapLock->GetStride(&cbStride);

UINT cbBufferSize = height * cbStride;
BYTE *pbBuffer = new BYTE[cbBufferSize];

piBitmapSource->CopyPixels(&prc, cbStride, cbBufferSize, pbBuffer);
piBitmap->Release();


////////////////////////////////////////////////////////////////////////////////////////////////
// how to convert each RGB channel value(2 Byte) to float or something..
///////////////////////////////////////////////////////////////////////////////////////////////
INT *tmp = new INT[cbBufferSize];

for(UINT i=0;i<cbBufferSize;i++){
tmp[i] = static_cast<INT>(pbBuffer[i]);
}
////////////////////////////////////////////////////////////////////////////////////////////////


if (SUCCEEDED(hr))
{
hr = piFrameEncode->WritePixels(height, cbStride, cbBufferSize, pbBuffer);
}


//Commit the frame.
if (SUCCEEDED(hr))
{
hr = piFrameEncode->Commit();
}
}


if (SUCCEEDED(hr))
{
piEncoder->Commit();
}

if (SUCCEEDED(hr))
{
//piFileStream->Commit();
}

Cleanup:
if (piFileStream)
piFileStream->Release();
if (piEncoder)
piEncoder->Release();
if (piBlockWriter)
piBlockWriter->Release();
if (piBlockReader)
piBlockReader->Release();

return 0;
}

==============================================================================






Re: How to modify the pixel value of RAW image (.cr2) and save(encoding) again ?

Andi Fein

Every even array of 'tmp' has '0', and every odd array has RGB pixel value from 0 to 255.

I worried about the result means that the CopyPixel function does not returns 16bit pixel value.

This is the correct result. CopyPixels is returning 16 bit pixel values, it's just that the low byte of each pixel value is always zero.

How I can get raw pixel values

These are the raw pixel values that the CR2 codec is returning. WIC is not touching the values at all.






databaseforum