# Preserving Alpha values when using writeImage with a surface16u

**URL:** <https://discourse.libcinder.org/t/preserving-alpha-values-when-using-writeimage-with-a-surface16u/158>\
**Category:** Using Cinder\
**Created:** [July 16, 2016, 7:07pm UTC](https://discourse.libcinder.org/t/preserving-alpha-values-when-using-writeimage-with-a-surface16u/158 "2016-07-16T19:07:16Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Craigson](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/craigson/32/43_2.png) [@Craigson](https://discourse.libcinder.org/u/Craigson)\
**Post date:** [July 16, 2016, 7:07pm UTC](https://discourse.libcinder.org/t/preserving-alpha-values-when-using-writeimage-with-a-surface16u/158/1 "2016-07-16T19:07:16Z")

</div>

Greetings,

I’m trying to manipulate the alpha values of a PNG image and preserve the manipulated values after writing the image.

I’m loading the image using the following:

`mSurface16 = Surface16u::create( loadImage( path ) );`

Then manipulating the alpha values like so:

```
for (int i = 0; i < 300 ; i ++)
{
    auto pixel = mSurface16->getPixel(ivec2(i,0));
    mSurface16->setPixel(ivec2(i,0), ColorA(pixel.r, pixel.g, pixel.b, pixel.a - i));
    cout << "pixels new alpha: " << pixel.a << endl;
}

```

when reloading the image using:

```
    mSurface16 = Surface16u::create( loadImage( path ) );
    
    for (int i = 0; i < 300; i++)
    {
       auto pixel = mSurface16->getPixel( ivec2(i,0) );
       cout << "pixelalpha: " << pixel.a << endl;
    }

```

The values all remain unchanged at 65535…

Any thoughts would be welcomed.

Thanks!

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [July 16, 2016, 11:15pm UTC](https://discourse.libcinder.org/t/preserving-alpha-values-when-using-writeimage-with-a-surface16u/158/2 "2016-07-16T23:15:01Z")

</div>

Are you saving the file? The `setPixel` function only manipulates data in RAM.

---

<div class="post-metadata">

**Author:** ![Craigson](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/craigson/32/43_2.png) [@Craigson](https://discourse.libcinder.org/u/Craigson)\
**Post date:** [July 17, 2016, 3:33am UTC](https://discourse.libcinder.org/t/preserving-alpha-values-when-using-writeimage-with-a-surface16u/158/3 "2016-07-17T03:33:26Z")

</div>

Hi Paul,

Yes i am, stupid mistake leaving that part out… Using:

```
fs::path path = getSaveFilePath();
if( ! path.empty() ) {
   // Surface16u s16( mTexture->createSource() );
    writeImage( writeFile( path ), *mSurface16);
}

```

Reloading the file after writing to disk yields all values of 65535 for alpha using mSurface16-\>getPixel(ivec(i,j))

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [July 17, 2016, 10:55am UTC](https://discourse.libcinder.org/t/preserving-alpha-values-when-using-writeimage-with-a-surface16u/158/4 "2016-07-17T10:55:15Z")

</div>

Does the PNG have an alpha channel to begin with? If not, `getPixel` will always return the maximum value and `setPixel` will ignore the alpha value.

Also, I’m not sure `setPixel` supports 16-bit PNG’s, judging by the [source code](https://github.com/cinder/Cinder/blob/e94f43d9bb9a0be34e65f542d238e254e61e0122/include/cinder/Surface.h#L248). I could be wrong, though.

---

<div class="post-metadata">

**Author:** ![Craigson](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/craigson/32/43_2.png) [@Craigson](https://discourse.libcinder.org/u/Craigson)\
**Post date:** [July 17, 2016, 2:56pm UTC](https://discourse.libcinder.org/t/preserving-alpha-values-when-using-writeimage-with-a-surface16u/158/5 "2016-07-17T14:56:47Z")

</div>

Hi Paul,

As a point, the original image does not have an alpha channel. However, if I ignore the fact that I’m loading an image and simply create a surface and populate each pixel with random values, it seems to work. For example:

```
mSurfaceOut = Surface16u::create(1024,768,true); // changed from Surface::create
int w = mSurface16->getWidth();
int h = mSurface16->getHeight();
    
    for (int i = 0; i < w ; i ++)
    {
        for (int j = 0; j < h ; j ++)
        {
            int16_t r = randInt(0, 65535);
            int16_t g = randInt(0, 65535);
            int16_t b = randInt(0, 65535);
            int16_t a = randInt(0, 65535);
            
        mSurfaceOut->setPixel(ivec2(i,j), ColorA(r, g, b, a));
        //cout << "pixels new alpha: " << pixel.a << endl;
        }
    }

```

will produce an image like this 🙂

 ![](https://canada1.discourse-cdn.com/flex030/uploads/libcinder/original/1X/a30c13a377b776797ff522653f9746731fa9b25f.png)

Something to note here is that if I declare any of the r,g,b, or a variables as int32\_t this does not work.

However, when I then load this image in using:  
`mSurface16 = Surface16u::create( loadImage( path ) );`

The r,g,b, and a values are either 0 or 65535. The image I’ve included above is definitely a 16-bit image and contains an alpha channel… I’m just getting a bit lost as to why it’s maxing/zeroing out the values, and why it’s not preserving any changes to the alpha channel.

---

<div class="post-metadata">

**Author:** ![rich.e](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/rich.e/32/1025_2.png) [@rich.e](https://discourse.libcinder.org/u/rich.e)\
**Post date:** [July 17, 2016, 3:29pm UTC](https://discourse.libcinder.org/t/preserving-alpha-values-when-using-writeimage-with-a-surface16u/158/6 "2016-07-17T15:29:41Z")

</div>

Shouldn’t the first line above be

```auto
mSurfaceOut = Surface16u::create(1024,768,true);

```

? And mSurfaceOut should be of type `Surface16u`, as `Surface` uses `uin8_t`s.

---

<div class="post-metadata">

**Author:** ![Craigson](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/craigson/32/43_2.png) [@Craigson](https://discourse.libcinder.org/u/Craigson)\
**Post date:** [July 17, 2016, 3:43pm UTC](https://discourse.libcinder.org/t/preserving-alpha-values-when-using-writeimage-with-a-surface16u/158/7 "2016-07-17T15:43:02Z")

</div>

You’re quite right Rich, it is that way in my code, I wrote this reply away from my laptop and didn’t have the code on hand. The line in the code is in fact:

```
mSurfaceOut = Surface16u::create(1024, 768, true);
```

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [July 18, 2016, 12:04am UTC](https://discourse.libcinder.org/t/preserving-alpha-values-when-using-writeimage-with-a-surface16u/158/8 "2016-07-18T00:04:08Z")

</div>

So yeah, make sure that the original PNG actually has an alpha channel, otherwise neither the `getPixel` or `setPixel` function will do anything meaningful. Also, use `uint16_t` (unsigned), otherwise you’ll get invalid results for values above 32767.

---

<div class="post-metadata">

**Author:** ![Craigson](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/craigson/32/43_2.png) [@Craigson](https://discourse.libcinder.org/u/Craigson)\
**Post date:** [July 18, 2016, 2:08pm UTC](https://discourse.libcinder.org/t/preserving-alpha-values-when-using-writeimage-with-a-surface16u/158/9 "2016-07-18T14:08:13Z")

</div>

Thanks Paul, I’ll give this a try and let you know. Is a viable workaround for loading an image that has no alpha channel, like a JPG, creating a new Surface!6u with an alpha channel ( mSurfaceOut = Surface16u::create(1024, 768, true) ) and manually setting RGB values based on the original image’s color data, then giving it an alpha value of my choosing?

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [July 18, 2016, 10:42pm UTC](https://discourse.libcinder.org/t/preserving-alpha-values-when-using-writeimage-with-a-surface16u/158/10 "2016-07-18T22:42:46Z")

</div>

I guess so, but JPG’s are always 8-bit as far as I know, so you’d have to only set the hi byte of the 16-bit value and set the lo byte to zero (in other words: convert 8-bit to 16-bit). Be careful to properly skip/set the 16-bit alpha word, based on whether you’re using ARGB or RGBA. And of course be aware of [endianness](https://en.wikipedia.org/wiki/Endianness). You’ll probably have to experiment a little.

---

<div class="post-metadata">

**Author:** ![Craigson](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/craigson/32/43_2.png) [@Craigson](https://discourse.libcinder.org/u/Craigson)\
**Post date:** [July 18, 2016, 10:53pm UTC](https://discourse.libcinder.org/t/preserving-alpha-values-when-using-writeimage-with-a-surface16u/158/11 "2016-07-18T22:53:57Z")

</div>

Thanks Paul, as always mich obliged.
