TIP:            166
Title:          Reading and Writing the Photo Image Alpha Channel
Version:        $Revision: 1.9 $
Author:         Donal K. Fellows <donal.k.fellows@man.ac.uk>
State:          Draft
Type:           Project
Vote:           Pending
Created:        19-Nov-2003
Post-History:   
Keywords:       Tk,image get,image put
Tcl-Version:    8.7

~ Abstract

This TIP describes how to update the '''image get''' and '''image put'''
subcommands so as to allow script-level access to the full alpha
channel information that has been present in the photo image data
model since Tk 8.3.

~Rationale

Alpha channels.  We've had them in Tk's photo image data model (which
is currently 8-bits-per-channel RGBA) for quite some time now.  We can
copy the alpha data around inside the image.  We now display them
correctly on deep-enough displays (many thanks to the people who have
worked on that!)  But can we write alpha data into an image?  No.  Not
unless you have an image format handler that produces alpha data
installed (e.g. the PNG from tkimg.)  I think we should fix this so
that people can read and write the full alpha data from scripts.

~Proposal

I propose to update the ''photoImageInstance'' '''get''' subcommand so
that it returns four values instead of three, with the fourth being the
contents of the alpha channel for the pixel.

I also propose to update the ''photoImageInstance'' '''put''' subcommand
so that alpha channel information may be specified in the following ways
when using the list-of-lists-of-pixel-data format (the image-format
format will be up to the particular image format code, as always.)

 * If a pixel is specified as being the empty string, that pixel will
   be set to be completely transparent.  This parallels the
   interpretation of the empty string as transparency elsewhere within
   the core (notably in [[canvas]] items.)

 * Any pixel colour format that is not the empty string (e.g.
   ''bisque2'' or ''#abcdef'') may have the following suffix added -
   '''@A''' - where A is a fractional alpha value in the range 0.0
   to 1.0 (which values correspond to fully transparent and fully opaque
   respectively.)

 * Any pixel colour format that is not the empty string and which does
   not have a '''@A''' suffix may have a '''#XX''' suffix, where XX is a
   pair of hex digits that specify an integer alpha value in the range
   0 (fully transparent) to 255 (fully opaque).

 * Any pixel colour format that is not the empty string and which does
   not have a '''@A''' suffix may have a '''#X''' suffix, where X is a
   single hex digit that specifies an integer alpha value in the range
   0 (fully transparent) to 255 (fully opaque).  This is expanded in
   range from 4 bits wide to 8 bits wide by multiplication by 0x11.

 * All pixel colours that have neither of the foregoing suffixes are
   to be interpreted as being fully opaque, which is the current
   situation anyway.

 * An additional pixel format is to be supported, consisting of a Tcl
   list of three or four integers in the range 0 to 255, being the
   value of the red channel, green channel, blue channel and alpha
   channel respectively in that order.  An absent alpha channel is to
   be interpreted as full opacity.

 * Two additional pixel formats are to be supported, consisting of a
   '''#''' followed by exactly four or eight hexadecimal digits.  When
   four digits are present, they will be interpreted as containing data
   for the ''ARGB'' channels (in that order), and each digit will be
   expanded internally to 8-bits wide by multiplication by 0x11.  When
   eight digits are present, they will be interpreted as containing data
   for the ''ARGB'' channels (in that order) with two digits for each
   channel.

 > Note that these formats are '''#ARGB''' not '''#RGBA''' because
   '''#ARGB''' seems to occur more commonly on the web and the other way
   round can be written with the addition of an extra '''#''' (i.e. as
   '''#RGB#A''').

Additionally, the ''photoImageInstance'' '''transparency''' command's
subcommands will be updated in the following way:

 * The '''get''' subcommand will be modified to take an extra option,
   '''-alpha''' (to be placed after the coordinates), that modifies the
   result to be the integral alpha value (in the range 0 to 255) for the
   specified pixel. Without the option, the result shall continue to be
   a boolean that is true exactly when the pixel is wholly transparent.
   Also supported will be a '''-boolean''' option (in the same position)
   which will be interpreted as meaning the current behaviour.  Only one
   of the two options will be allowed.

 * The '''set''' subcommand will be modified to take an extra option,
   '''-alpha''' (to be placed after the coordinates), that modifies the
   interpretation of the following value so that it is the integral
   alpha value to be set for the pixel.  Similarly to the '''get'''
   command, there will also be a '''-boolean''' option to indicate the
   current behaviour, and which will mutually exclusive with the
   '''-alpha''' option.

~Examples

Create a small image with a black border and a partially-transparent
red area in the center.

|image create photo transExample
|transExample put black -to 0 0 10 10
|transExample put red@.5 -to 2 2 8 8

Retrieve the alpha value of a pixel near the middle of the image
created previously.

|set aVal [transExample transparency get 5 5 -alpha]

Create a green box with a simple shadow effect

|image create photo foo
|# Make a simple graduated fill varying in alpha for the shadow
|for {set i 14} {$i>0} {incr i -1} {
|   set i2 [expr {$i+30}]
|   foo put [format black#%x [expr {15-$i}]] -to $i $i $i2 $i2
|}
|# Put a solid green rectangle on top
|foo put #080 -to 0 0 30 30

~Reference Implementation

Nothing yet.

~Copyright

This document is placed in the public domain.
