I want to use two options for color or grayscale images in PictureBox:
1. Use dithering to make it monochrome
2. Use reduce color depth to nearest colors of selected palette
1.
I don't know about dithering too much, only know that Floyd Steinberg is good and many times used.
So, how to dither color or grayscale images in PictureBox?
2.
I have 16, 128 and 256 color palettes and need to reduce color depth by nearest color of palette (16 color = 4bit / 128 color = 7bit / 256 color = 8bit)
Like: color of pixel is brown and palette has near colors only yellow and orange - this recolors pixel to orange - is lighter than brown, but very close color instead of yellow and so on.
Here is example of one application which does this:
This application for other purposes and I need to do anything similar.
It uses CGA color palette to render nearest color.
Color reduction to 4, 7 or 8 bit, using generic palettes, rarely produces great results when there are lots of colors in the source image. There is no magic palette that will work with all images. However, there are processes to create "adaptive palettes". The process is fairly complex and there are VB examples about. The process of creating adaptive palettes produces a palette that tends to best fit the source image.
Insomnia is just a byproduct of, "It can't be done"
Greyscale is not monochrome - there's always balance if is pixel lighter ior more dark to set it as white or black - even greyscale is not 1bpp...so I mean exactly black & white...
I don't want use generic palettes.
To explain:
I'm retrocomputer programmer programming mainly Commodore computers - C128, C16, C65 and C64.
Each computer has own palette, not generic, and how can display computer in 16 colors adaptive palette?
Really want to use custom palettes 4, 7 and 8bit.
Problem is that really don't know how...
Dithering - some graphic modes using only 2 colors - so are monochrome, example:
640x576 in 16 colors fits to VideoRAM, but 800x600 fills VideoRAM by bitmap so, that color information has no enough place, so mode sis monochrome.
So, I can't use greyscale, I must to use black and white = monochrome...
Just to throw that out there, but not wanting to quibble over semantics.
Adaptive palette routines allow reduction anywhere from 256 to 2 colors. Googling "VB6 Adaptive Palette" or "VB6 Optimize Palette" may be helpful. Results get poorer the smaller the palette.
There are several different methods of producing B&W color reduction. Most will attempt simple routes like using GetDIBits API or looping thru colors and taking any pixel's RGB average > 127 to white else black. Just like palettes, no algo is truly generic for all images. Dithering helps keep the image recognizable during color reduction.
Tanner will likely jump in at some point, he's kinda the color-guru on this site. His app that you are aware of probably has all the info you need to help develop your routines.
Insomnia is just a byproduct of, "It can't be done"
Ok, to make it correct...
"Not all monochrome images are black and white"
Yes, but always it is 1bpp - in image is simple info for foreground color and background color, nothing more.
Videochip of Commodoroe 128 it does the same - has one register where is stored foreground and background color.
This info can make black and white image aqua-blue image... or is it mistake?
Reducing color depth to nearest is dithering too?
Really here I'm lost... here is example - original-nearest-Floyd Steinberg (both using CGA palette):
Nearest method is for me important 'cause user can make monochrome image by dithering with many editors, but nearest color is not available anywhere and even not with selected palette.
Can you help me?
Thank you for help and suggestions.
Miro
Hi Mirkosoft. I'm a little confused by your request here. It sounds like you want to make images that use the Commodore 64 color palette. Are you sure you need VB code to do this? Or are you just looking for any software that will let you save images using a custom palette?
If you just want to generate images using the C64 palette, you can use the open-source photo editor GIMP. It describes the process here:
You can, however, create an ordinary palette from the colors in an indexed image—actually from the colors in any image. To do this, choose Import Palette from the right-click popup menu in the Palettes dialog: this pops up a dialog that gives you several options, including the option to import the palette from an image. This possibility becomes important if you want to create a set of indexed images that all use the same set of colors.
Once you've saved the C64 palette in GIMP, you can apply it to any image you want by using the Image > Mode > Indexed option, and selecting your saved palette under the "Custom Palette" option.
Using existing software to do this will be much easier than doing it in VB code. I could send you a (large) chunk of VB code to do the same thing, but it's all code that has already been mentioned to you in other threads, and I worry that it would not be easy for a beginner to comprehend.
Why in VB?
I'm creating app to handle images to process them to use with Commodore 128 VDC chip - please read carefully: NOT Commodore 64.
I want to give user all comfort to do that.
No one, even me not, know about Gimp function...
@Mirkosoft: From this thread and other ones you've recently posted, I worry that you're in way over your head on this topic. Let me try to explain.
Producing images for use on any Commodore emulator is much more complicated than just "applying a palette". Depending on what graphics mode the VIC or VDC is running in (both exist in a C128), each tile on the screen (8x4 pixels, typically, but pixels are double-width) supports 3 palette entries, with a 4th entry reserved for a dedicated backcolor. Also, some modes only support foreground/background colors per tile, while sprites obey totally different rules - it's all quite complicated.
So for actual use on a C128 emulator, you can't just apply a 16-color palette to the entire screen - you have to subdivide the screen into chunks, and apply specific sub-palettes to each chunk. No standard image format supports this type of storage, so these types of decisions are typically baked directly into a ROM.
Now if you just want to have fun and make an image "look" like a Commodore-era image, then sure - you can apply a 16-color palette and get a "close enough" result. But this is a far cry from actually using the image in an emulator.
The reason I bring this all up is that each Commodore emulator typically has their own method for addressing these items. Without knowing these kinds of details, I worry that we'd be putting a lot of work into features that probably won't work they way you expect. There are dedicated emulator forums that already address these issues in great detail, and if you're not already familiar with how your emulator of choice works, you may want to study up on it before working on tools to interact with it.
Does any of this help? There may be other Commodore experts on here that could provide more useful information...
Last edited by Tanner_H; Aug 14th, 2017 at 10:40 AM.
Sorry for not complete explaining:
Of course I know about non-chunky picture display and attribute clash - even interlaced modes producing 136 colors instead 16 - smallest attribute clash is in C128 VDC 8x1 pixel.
I don't want to convert pictures to Commodore format - this part of code did my friend.
I want to add options to "prepare image for procesing to Commodore format".
Why?
Sometimes Floyd Steinberg dithering produces after creating Commodore format picture not so good image like nearest color.
I used it by other application and I want to apply nearest color in my application...
And for monochrome images auto-dithering by Floyd Steinberg when is used color or grayscale image - here's not attribute clash and I created also code for processing it to Commodore 128 format...
So, this is situation. I meant that here on this forum for PC computers is not interesant writing about Commodores.
If I needs to grab any true color image, and downgrade it to C64 screens mode, I would use brute-force.
lets. explain, I don't know exactly the limitations of C64 VDP, but know about MSX's VDP (the enemy).
and It is not just 16colors limitation, but two paletes selectables per 8 pixels horizontally. IIRC C64 has something similar.
So, knowing the exact RGB component of the 16 palletes (15 in real, because pal0 = pal1 in MSX).
I would try to grab the smaller independent block. setup in brute force all convinations, and in each convination compare against the original image, on that comparation I would qualify it, in an ERROR scale.
brute force all posibles value for the minimal independent block, and pick the one which does less error difference compared against the original image.
If in MSX1, it is 256 values *16*16 so the loop is 256(8bits)*(16forecolor pal)*16(backcolor pal) per each 8 horizontal pixels. It is not that big.
For that, you must know the exact heavyness in R G B of each palette. if the pixel bit is 1 , pick the current forecolor pal, if it 0 pick the current backcolor pal,
then compare the color of the pal with the original pixel , sum the differences, with ABS(difference) so all positive number will sum the R difference + B difference + G difference per that pixel. loop it to the 8 pixels in the row... and you get how much difference of that 8 pixels row.
qualify all possibles values for those 8 pixels, pick the best one.
for PCs speed, it is easy cake.
EDIT: Also I would try to adjust the error calculation because a difference in the blue channel hasn't the same impact than the same numerical error in the red channel or the green channel. As human eye is sintonized about the yellow frequency.
Last edited by flyguille; Aug 14th, 2017 at 01:46 PM.
Thank you for clarifying, Miro. Sorry to ask so many questions - I just wanted to make sure you were getting advice that would actually help you, instead of leading you down a wrong path.
DEXWERX shared a dithering link with you that I think could be helpful. (Some famous names have referred to that article in the past, so I think it's not too terrible... ) Dithering to monochrome is an easy task to understand, and since you already have code for monochrome color reduction from LaVolpe, I think it would be a great exercise for you to add dithering support to it. Others could do it for you, but since you have a big interest in emulating Commodore graphics, this seems like a nice task for a beginner to tackle, to help you get comfortable with image processing.
Similarly, applying a predefined palette to an existing image is not too hard, and flyguille has already described the basic steps to you in detail. I have a Palettes module here that I wrote for my PhotoDemon project. It has sample code for generating an optimal palette from an existing image, applying a palette to an existing image, and there is an entire function called ApplyPaletteToImage_Dithered that basically does exactly what you need.
Of course, my sample code is going to use some APIs and objects (like DIB wrappers) that you don't want in your project. You'll have to make some small changes to make the code operate on picture boxes, perhaps by using GetDIBits like LaVolpe has shown in the code he's previously shared with you. (SetPixel and GetPixel could also work, and for small images, their performance will be fine.)
I'm happy to help if any questions arise, but I think you have all the pieces you need to tackle this yourself. (Or maybe you can find someone with lots of free time to do it for you; unfortunately this is more than I can tackle right now!)
I was reading page in link. Maybe I can to do 8 color palette, but I'm lost how to apply 16 color palette.
C128 VDC chip has near identical palette like CGA - only dark yellow is bit orange.
I understand not how to apply it to 16 color palette... can you help me, or explain better?
So , with paqlette is not so big problem - only source, so here are values (I think best is to choose CGA values):
Code:
color emulator CGA official
----------------------------------------------------------------
Dark Black #000000 #000000 #000000
Light Black #6B6B6B #555555 #404040
Dark Blue #0000B9 #0000AA #0000A0
Light Blue #6B6BFF #5555FF #4040FC
Dark Green #00B800 #00AA00 #00A000
Light Green #6AFE6A #55FF55 #40FC40
Dark Cyan #00B9B9 #00AAAA #00A0A0
Light Cyan #6BFFFF #55FFFF #40FFFF
Dark Red #B80000 #AA0000 #A00000
Light Red #FE6A6A #FF5555 #FF4040
Dark Purple #B900B9 #AA00AA #A000A0
Light Purple #FF6BFF #FF55FF #FF40FF
Dark Yellow #B86A00 #AA5500 #A06000
Light Yellow #FEFE6A #FFFF55 #FFFF40
Dark White #B9B9B9 #AAAAAA #A0A0A0
Light White #FFFFFF #FFFFFF #FFFFFF
Problem is in resolution.
It's wide range of resolutions - custom etc. for example 640x256, 720x700, 800x300, 800x288, 320x256, 800x600.
But here is also req'd to say - if is mode higher resolution than 640 horizontallly, then mode can be only monochrome (only two colors by user's choice - foreground and background) - VDC chip sync fails applying colors over than 640H.
Ok, resolution minimal: here is possible to say that lower than 320x200, but we can say 320x200 as minimal, maximal: reached 800H 800V - to VideoRAM fits only 800x600 or 600x800; referred maximum is 1024x800.
But we can give all possible resolutions far away, I want to create program for seven resolutions:
256x192
320x200
320x256
320x400 interlaced
512x384 interlaced
640x400 interlaced
640x512 interlaced
- all modes have attribute clash that in 8x2 pixels can be only 2 colors except first (256x192) - it has clash 8x1 pixel (again VDC sync - 480 pixels and higher cannot reach 8x1 attribute clash, only 8x2 or custom larger).
Official mode at Commodore 128 preview was 320x200 for VIC-IIe chip and 640x200 VDC chip (VideoRAM 16K limit), at preview Commodore 128DCR VDC got 64K VideoRAM.
Block is attribute clash, explaining;
Normally bitmaps have value in colors for each pixels - 256 color bitmap has for one pixel one byte.
Commodore 128 it has different.
Normal text attributes are high nibble RVS, Alternate, Flash, Underline and low nibble character color - and from this is created block.
Normally is block 8 pixels wide and 8 pixels high.
By trick is possible to reduce block to 8 pixels wide and 1 pixel high - so only one 8 pixel row - but it is for sync problem so I explain 8x2 block:
Block can be 8 pixels wide - not more not less - it is from text mode written above.
Block can be 1 pixel up to 32 pixels high - and this means attribute clash.
8x2 pixels block:
bitmap - bits
10011011
00001111
color - F = foreground, B = background
BBBBFFFF
applied:
FBBFFBFF
BBBBFFFF
So, 8 pixels horizontally and 2 pixels vertically have set only 2 colors of 16 (4-bit colors) - Foreground for bits set 1, Backgound for bits set 0.
So, bitmap information with color has 3 bytes:
1 byte = first 8 pixels vertically
1 byte = second 8 pixels vertically
1 byte = forground and background 4-bit colors (16 colors)
But bitmap and colors are stored separatelly - again from text mode.
I don't know if you understand it, if not I try to explain again.
I have last Q: have you source code of dithering in image examples?
Now I correctly installed Visual Studio 6.0 on Windows 10 x64 and tried to look on project - it's lot of investigation.
Simply - if I can ask - can you create 16 color (4-bit) dithering? Applying Commodore color cells can do by myself and can share.
Now I correctly installed Visual Studio 6.0 on Windows 10 x64 and tried to look on project - it's lot of investigation.
Simply - if I can ask - can you create 16 color (4-bit) dithering? Applying Commodore color cells can do by myself and can share.