Extending palette of indexed images in MATLAB - matlab

I extracted the color palette of an indexed image - a 256x3 matrix, duplicated the palette to 512x3 matrix with duplicate values in each half. What I want to do is steganography. When the secret message bit is 0,I want to refer to one half of palette, else to the other half. In this way, we can get lossless steganography in indexed images!
But when I try to save the image as bitmap with the new color map, it says bmp/gif files cannot have more than 256 entries in the color palette!
[im,map]=imread('mandril_color.gif');
nmap=zeros(512,3);
nmap(1:256,1:3)=map(1:256,1:3);
nmap(257:512,1:3)=map(1:256,1:3);
imwrite(im,nmap,'palette1.gif');
The above was my code to just test whether saving an image with an extended palette works or not.. unfortunately it did not. How can I avoid this problem and have a custom palette with more than 256 values?

The standard for .bmp and .gif only supports color palettes of length 256. There is no way around that for you.
To use color palettes with more than 256 entries, you can use .jpg, for example. Make sure you choose lossless compression, since otherwise, your message will be scrambled.

Related

PIL simple image paste - image changing color

I'm trying to paste an image onto another, using:
original = Img.open('original.gif')
tile_img = Img.open('tile_image.jpg')
area = 0, 0, 300, 300
original.paste(tile_img, area)
new_cropped.show()
This works except the pasted image changes color to grey.
Image before:
Image after:
Is there a simple way to retain the same pasted image color? I've tried reading the other questions and the documentation, but I can't find any explanation of how to do this.
Many thanks
I believe all GIF images are palettised - that is, rather than containing an RGB triplet at each location, they contain an index into a palette of RGB triplets. This saves space and improves download speed - at the expense of only allowing 256 unique colours per image.
If you want to treat a GIF (or palettised PNG file) as RGB, you need to ensure you convert it to RGB on opening, otherwise you will be working with palette indices rather than RGB triplets.
Try changing the first line to:
original = Img.open('original.gif').convert('RGB')

Read "simple" transparent PNG in Matlab

I am trying to use PNG images as Toolbar icons. I am currently reading them with imread an set the corresponding CData value.
Now I have some images with transparency. There is no alpha channel (I found some threads with solutions for that), but I get some kind of "Simple Transparency". The imfread function returns "simple" for the Transparency field and a vector of values between 0 and 1 for the SimpleTransparencyData field.
I couldn't find any information about this transparency type neither in the Matlab help nor the internet. So I would like to know if it is possible to show the transparent image in the toolbar directly, or if not how to composite the transparent values with the toolbar's background color.
In summary you set the CData value to be a NaN to represent transparency.
See this article that I wrote on undocumentedmatlab.com which describes how to do it for uicontrols.
For a toolbar icon you modify the CData property in the same way - the primary difference is that you dont need to modify the backgroundcolor property.
I did a quick test on the only solution I could probably imagine and it really seems to work:
I forgot to mention, that I am using indexed PNG files for this. But this sort of transparency seems to imply this fact.
The indexed colors are ordered that the (partially) transparent colors are at the beginning of the table. The SimpleTransparencyData now specifies the transparency of each of the indexed colors. Non-transparent colors are left out, as there are more colors than transparency values.
With that additional information it is easy to composite a single background color with the image.

Transparency with JPEGs

JPEGs are smaller in size than PNGs. So, I thought that if I can make a specific region in a JPEG-file transparent, with some code, maybe I can save some bytes.
So does anyone know how to achieve this with for example PHP or JavaScript?
No. You can't do this. JPGs do not support alpha channels and have no capacity to designate certain colors as transparent either (GIF-style).
There's several issues with this, all of them have to do with that JPEG is a lossy compression format. The JPEG format is optimized for natural images and sharp edges will get blurred. If you intend that a specific pixel should have the value #d67fff there's no guarantee that after color conversion, FDCT, quantization, IDCT and color conversion, the pixel still will have that value. There's also a strong possibility that that pixel value will occur in areas that you don't want.
No. JPEG does not support transparency and is not likely to do so any time
soon. http://www.faqs.org/faqs/jpeg-faq/part1/section-12.html
You cannot do that, the client renders the image and doesn't know that you want it to treat that color as transparent (plus various compression methods on jpeg wouldn't work well with transparencies anyway).
I believe you can go with an 8-bit custom-pallet png, should save you a lot of space. Otherwise 24-bit PNG is your only high color option.
You can convert your image to SVG containing a color information as JPEG and an alpha channel as grayscale mask. Here is a tool I wrote to do it https://github.com/igrmk/transpeg

Getting rid of interpolation/aliasing in EPS export of matlab?

I have a 2D color-map plot created with imagesc and want to export it as a .eps file using
print -depsc.
The problem is that the "original" image data is from a rather small matrix (131 x 131). When I view the image in the matlab figure window, I can see all the individual pixels if I zoom a bit closer.
When I export to eps, however, there seems to be some interpolation or anti-aliasing going on, in that neighboring pixels get blurred/blended into each other. I don't get the problem if I export a high-resolution tiff, but that format is not an option (as demanded by a publisher).
How can I obtain an eps that preserves the pixely structure of my image without applying interpolation or anti-aliasing?
The blurring actually depends on the rendering software your viewer application or printer uses. To get good results all the time, make each pixel in your image an 8x8 block of pixels of the same color. The blurring then only affects the pixels at the edge of each block. 8x8 blocks are best as they compress without nasty artifacts using DCT compression (sometimes used in eps files).
Old question, but highly ranked in Google, so here is my answer:
Open the .eps-file with a text editor, search for "Interpolate" and change the following "true" to "false". Repeat that step for all Interpolate-statements.
It might also depend on the viewer you're using, but probably just because some viewers ignore the "Interpolate"s...
Had the same problem using plot2svg in Matlab and exporting from Inkscape to eps.

iOS 256 Colors (VGA) to RGB

I'd like to convert a VGA color (256 colors; 8 bit) to a RGB color on iOS.
Is it possible to compute this or do I have to use color tables (using CGColorSpaceCreateIndexed).
UIColor does not support 256 Colors.
Thanks :)
Somewhere, the title you're porting should have set the palette. On the VGA, the 256 colours are mapped through a table that the programmer has previously set to convert them into 18 bit RGB colour (at a uniform 6 bits per channel). If you're running the original title through emulation then watch for writes to ports 0x3c6, 0x3c8 and 0x3c9 or calls to the BIOS via int 10h, with ax = 0x1010 (to set a single colour) or 0x1012 (to set a range). If you have the original code, obviously look for the source of the palette table.
In drawing terms, you can keep the palette yourself, for example as a C-style array of 256 CGColorRefs, or use CGColorSpaceCreateIndexed as you suggest (ignore Apple's slight documentation error; the colour table can contain up to 256 entries, not up to 255) probably with a bitmap context to just pass your buffer off to CoreGraphics and forget about it.
I expect the remapping will be performed on the CPU, so if that gets a bit too costly then consider using GL ES 2.x and writing a suitable pixel shader — you'd upload your actual image as, say, a luminance (ie, single channel) texture, plus a 256x1 texture where the colour at each spot is a palette entry, then write a shader that reads from the first texture for the current texture coordinates and uses that value to index the second.