From: Peter Duniho on 7 Dec 2009 12:53 Jay Dee wrote: > I have an application that stores colour text to file currently as 4 > bytes for each character (Char, Red, Green, Blue). As you can imagine, > this creates rather large files and is not ideal. > > The required selection of colours is minimal and the base 16 colours > available as standard in something like MS Paint would be sufficient. > > Is there a simple way to store a colour as 1 byte rather than 3? [...] As others have pointed out, you can create a color table, assuming you have no more than 256 different colors used in the text. The "rounding" approach you describe could work as well, but as you note will lose precision of the colors. Uwe's reply describes a way to do that. All that said, depending on the nature of the text, I think there are probably better ways than storing a color value with each character. When dealing with colored text, it's common for there to be groups of sequential characters all the same color. This is usually handled by indicating in the file the "current" formatting (e.g. color), and then assuming all characters following that format specification have the same format. Then, you only insert a format record in the file when the color changes. In fact, this is how the RTF file format works. Of course, it supports a very broad range of formatting options, and has its own overhead. But if your files are really so large as to cause a problem, it's possible that using RTF would be a good solution. It's portable, and there are already implementations available (for example, you could use the RichTextBox control to format text and then get the resulting RTF text). If you simply reduce your color value from 3 bytes to 1, at best your file sizes will reduce by half (assuming each character takes only 1 byte...if you're storing a multi-byte encoding, then obviously your size reduction is even less). If you want a more significant reduction, you may find it useful to store the color information as a bitmap, and then save the bitmap separately from the text (i.e. two parts in the same file, or two different files). If the color information is completely random, this probably won't help much, if at all. But assuming your color formatting for the text has some regularity to it, image compression algorithms should have some useful effect on the bitmap data, and could very well produce file size savings of _much_ better than 50%. Of course, if you use JPEG, you also have control over how much color information you lose, while PNG would be able to represent each color exactly but won't compress as much. Assuming you only need color information for each character (as opposed to other formatting information), and the text is suited to recording the color in the file only for when the character color changes (i.e. you have significant numbers of sequential characters all the same color), I think a custom character-run approach would probably be the best. It's simple, and should produce a dramatic reduction in file size. It also leaves the character data itself intact (i.e. without extra bytes between each character) so if you want to run the result through a simple compressor like GzipStream afterwards, you probably can get the file size down even much more. But I offer the other suggestions above for you to explore if you think they might work better in your scenario. Pete
From: Jeff Johnson on 8 Dec 2009 11:04 "Peter Duniho" <no.peted.spam(a)no.nwlink.spam.com> wrote in message news:esEyyY2dKHA.4880(a)TK2MSFTNGP05.phx.gbl... > As others have pointed out, you can create a color table Since this has been mentioned twice, I'll just add that images which use a color table are referred to as "indexed" images, and this table is called a "palette". You'll run across these terms when using graphics applications like PhotoShop or the GIMP.
From: Tim Roberts on 10 Dec 2009 01:34 "Jeff Johnson" <i.get(a)enough.spam> wrote: > >"Peter Duniho" <no.peted.spam(a)no.nwlink.spam.com> wrote: > >> As others have pointed out, you can create a color table > >Since this has been mentioned twice, I'll just add that images which use a >color table are referred to as "indexed" images, and this table is called a >"palette". You'll run across these terms when using graphics applications >like PhotoShop or the GIMP. It's fascinating to me that the Windows community has already forgotten about the concept of a palette. At the time Windows 95 was released, virtually every computer in the world had a graphics card with 8 bits per pixel, and every application programmer wasted half his time worrying about palette realization. -- Tim Roberts, timr(a)probo.com Providenza & Boekelheide, Inc.
From: Jay Dee on 22 Dec 2009 04:12 Thank you for your input and sorry it took so long to respond. I looked in to all the methods mentions above and decided not to round the colours like I first suggested. Bellow is the code I settled on after trying all the methods mentioned above. Many thanks for your help. Jay Dee #region List<byte> list = new List<byte>(); // 2 bytes, Int16, number of lines list.AddRange(BitConverter.GetBytes((Int16)this.chars.Count)); // each line for (int lineIndex = 0; lineIndex < this.chars.Count; lineIndex++) { // int16, length of the line list.AddRange(BitConverter.GetBytes((Int16)this.chars [lineIndex].Count)); // each char for (int charIndex = 0; charIndex < this.chars[lineIndex].Count; charIndex++) { // 1 byte as 'char' list.Add((byte)this.chars[lineIndex][charIndex]); } } // 1 byte, EnableBackColor list.Add(Convert.ToByte(this.EnableBackColor)); if (this.EnableBackColor) { if(this.chars.Count > 0 && this.chars[0].Count > 0) { Color color = this.charBackColors[0][0]; int count = 0; for (int lineIndex = 0; lineIndex < this.chars.Count; lineIndex ++) { for (int charIndex = 0; charIndex < this.chars [lineIndex].Count; charIndex++) { if (this.chars[lineIndex][charIndex] != '\0') { if (this.charBackColors[lineIndex][charIndex] != color) { // 4 bytes as integer, count list.AddRange(BitConverter.GetBytes(count)); // 3 bytes to store the color RGB list.Add(color.R); list.Add(color.G); list.Add(color.B); // count = 0; color = this.charBackColors[lineIndex] [charIndex]; } } count++; } } // 4 bytes as integer, count list.AddRange(BitConverter.GetBytes(count)); // 3 bytes to store the color RGB list.Add(color.R); list.Add(color.G); list.Add(color.B); } } // 1 byte, EnableForeColor list.Add(Convert.ToByte(this.EnableForeColor)); if (this.EnableForeColor) { if (this.chars.Count > 0 && this.chars[0].Count > 0) { Color color = this.charForeColors[0][0]; int count = 0; for (int lineIndex = 0; lineIndex < this.chars.Count; lineIndex ++) { for (int charIndex = 0; charIndex < this.chars [lineIndex].Count; charIndex++) { if (this.chars[lineIndex][charIndex] != '\0') { if (this.charForeColors[lineIndex][charIndex] != color) { // 4 bytes as integer, count list.AddRange(BitConverter.GetBytes(count)); // 3 bytes to store the color RGB list.Add(color.R); list.Add(color.G); list.Add(color.B); // count = 0; color = this.charForeColors[lineIndex] [charIndex]; } } count++; } } // 4 bytes as integer, count list.AddRange(BitConverter.GetBytes(count)); // 3 bytes to store the color RGB list.Add(color.R); list.Add(color.G); list.Add(color.B); } } // return list.ToArray(); #endregion
First
|
Prev
|
Pages: 1 2 Prev: C# for SQL Data Transfer Next: Graphics.DrawString character set problem |