|
Hi, guys. I have a slightly related question about compression. I've been banging out some code that uses the Imaging namespace's EncoderParameters to save an image as a multipage TIF. My problem is that the default compression schema appears to be LZW; or, at least, that is what some of my property readers are telling me. Anyway, I'm trying to save a multipage TIF with CCIT Group 4 Compression, but I get "invalid paramter" exception any time I try to add compression parameters.
Heath, do you have any experience with saving multipage TIFs with CCIT Group 4 compression in GDI+? If not, do you know anyone who does?
I can post my code, if you're interested.
|
|
|
|
|
In order to use a different encoding, there must be an encoder installed and registered with GDI and/or GDI+ to be used. This is done by passing the Guid of the encoder to the Encoding class, which you use with an EncodingParameter , which gets added to an EncodingParameters collection you pass when using Image.Save .
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Can I show you my code? It is just one console file.
|
|
|
|
|
What would it help? The fact remains that an encoder for the compression you're trying to use must be installed correctly on your system. You can use Encoder.Compression to create an Encoder . You can then use the EncoderValue to specify the compression you want to use. If you look at the documentation for the Encoder.Compression read-only, static property in the .NET Framework SDK, you'll even see an example of using a certain compression algorithm to save a TIFF.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
I know that I have the encoder installed on my machine because I can save single pages at G4 as well as multi-page tifs with the default compression, but I run into issues when I put the two together. My sample code reads a TIF file name from the app.config file, saves the first page in the file as a G4 image, saves the whole document as multipage file, but then fails when using the G4 EncoderParameter along with the save MultiFrame parameter. I'm using the same algorithm each time, just passing in addition EncoderParameters to the method.
The astrices show the problem:
using System;<br />
using System.Drawing;<br />
using System.Drawing.Imaging;<br />
using System.IO;<br />
<br />
namespace consoletest<br />
{<br />
class Class1<br />
{<br />
[STAThread]<br />
static void Main(string[] args)<br />
{ <br />
string testName = System.Configuration.ConfigurationSettings.AppSettings["testName"];<br />
string compName = "compressed.tif";<br />
string multiName = "multi.tif";<br />
string multiG4 = "multiG4.tif";<br />
<br />
System.Drawing.Image original = Bitmap.FromFile( testName ); <br />
<br />
try<br />
{ <br />
Image[] pages = Class1.ToImageArray( original );<br />
Class1.ToGroup4Compressed( pages[1], compName ); <br />
Class1.ToMultiPageImage( pages, multiName );<br />
Class1.ToMultiPageImage( pages, multiG4, Class1.GetGroup4Parameter() );<br />
}<br />
catch( Exception e )<br />
{ <br />
System.Diagnostics.Debug.WriteLine( e );<br />
}<br />
}<br />
<br />
public static Image[] ToImageArray( Image image )<br />
{<br />
int count = image.GetFrameCount( System.Drawing.Imaging.FrameDimension.Page );<br />
Image[] images = new Image[ count ];<br />
<br />
if( count > 1 )<br />
{<br />
for( int i = 0; i < count; i++ )<br />
{<br />
image.SelectActiveFrame( System.Drawing.Imaging.FrameDimension.Page, i ); <br />
images[ i ] = image.Clone() as Image;<br />
}<br />
}<br />
<br />
return images;<br />
}<br />
<br />
public static void ToGroup4Compressed( Image image, string fileName )<br />
{<br />
ImageCodecInfo info = GetCodec( "image/tiff" );<br />
Encoder enc = Encoder.Compression;<br />
EncoderParameters ep = new EncoderParameters();<br />
ep.Param[0] = new EncoderParameter( enc, (long) EncoderValue.CompressionCCITT4 );<br />
image.Save( fileName, info, ep );<br />
}<br />
<br />
public static Image ToMultiPageImage( Image[] pages, string fileName, params EncoderParameter[] p )<br />
{ <br />
Image image = new Bitmap( pages[0] ); <br />
FileStream stream = new FileStream( fileName, FileMode.OpenOrCreate );<br />
<br />
Encoder enc = Encoder.SaveFlag; <br />
ImageCodecInfo info = GetCodec( "image/tiff" );<br />
EncoderParameters ep = new EncoderParameters( p.Length + 1 ); <br />
ep.Param[0] = new EncoderParameter( enc, (long) EncoderValue.MultiFrame );<br />
<br />
int index = 1;<br />
foreach( EncoderParameter param in p )<br />
ep.Param[ index++ ] = param;<br />
<br />
image.Save( stream, info, ep );<br />
ep.Param[0] = new EncoderParameter( enc, (long) EncoderValue.FrameDimensionPage );<br />
for( int i = 1; i < pages.Length; i++ )<br />
image.SaveAdd( pages[ i ], ep );<br />
ep.Param[0] = new EncoderParameter( enc, (long) EncoderValue.Flush );<br />
image.SaveAdd(ep);<br />
<br />
stream.Close();<br />
return image;<br />
}<br />
<br />
public static EncoderParameter GetGroup4Parameter()<br />
{ <br />
return new EncoderParameter( Encoder.Compression, (long) EncoderValue.CompressionCCITT4 );<br />
} <br />
<br />
public static ImageCodecInfo GetCodec( string mimeType )<br />
{<br />
foreach( ImageCodecInfo ice in ImageCodecInfo.GetImageEncoders() )<br />
if( ice.MimeType.Equals( mimeType ) )<br />
return ice;<br />
<br />
throw new Exception( mimeType + " mime type not found in ImageCodecInfo" );<br />
}<br />
}<br />
}
|
|
|
|
|
Greetings,
I'm having some trouble while assigning a FormatProvider on a Datagrid column, namely a DataGridTextBoxColumn. I've defined a class that implements a IFormatProvider and a ICustomFormatter, that I intend to use on converting an integer to something like a time interval (01:33 21s).
Though the formatter has been created and linked to the FormatInfo of the dataGridTextBoxColumn, the data doesnt get converted. This is how I bind the formatter to the datacolumn:
<br />
DataGridTextColumn dgtc = grid.TableStyles[0].GridColumnStyles[4];<br />
TicksToTimeFormatInfo formatInfo = new TicksToTimeFormatInfo();<br />
dgtc.FormatInfo = formatInfo;<br />
dgtc.Format = "{0:tt}";<br />
The GetFormat method of the TicksToTimeFormatInfo class is called every time the grid draws a cell, but with NumberFormatInfo as the value's type. Even if i forge the function so that it always returns it's instance the Format implementation of the ICustomFormatter never gets called, I belive the NumberFormatInfo's one is called.
Does anyone knows how to solve this?
Thanks for your attention,
Anfernius
|
|
|
|
|
First of all, the Format property is wrong. You should use just "tt".
Second, there is a bug, IMO, that I have reported to Microsoft already. The DataGridTextBoxColumn format routines check if the data type implements IFormattable and, if it does, uses either the IFormattable.ToString implementation or a TypeConverter if the type supports it. If you are trying to use a primative type, this won't work.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
How does one retrieve the current applications Icon at runtime? I have a bunch of forms that I want to use the same Icon for as well as some plugins that may display forms.
I've tried resources namespace, this.Icon = new System.Drawing.Icon(Assembly.GetExecutingAssembly().GetManifestResourceStream("App.ico"));
and other items. I'm not finding much information on google, help, or other posts the the message boards.
Any help would be appreciated.
Thanks
Wayne
|
|
|
|
|
App.ico, the default icon for a project, isn't built as an embedded resource by default. It is used as the Win32 icon when your assembly is built and is embedded into the resource section of the PE/COFF executable (in the .rsrc section). When this icon is assigned to the main Form , it is actually embedded in a ResX file using base64 encoding (this gets compiled to a .resources file and embedded into the assembly).
You can either set this as an embedded resource by selecting the icon, going to the properties window, and set the Build Action to Embedded Resource. You can't just use App.ico, however. You must prefix it with the root namespace for your project, which is the name of the project by default. A better way so you don't have to remember this is to use the overloaded constructor for the Icon class using the main Form to get the namespace like so:
Icon ico = new Icon(typeof(MyForm), "App.ico"); The other way without having to embed the icon as a manifest resource is to P/Invoke the necessary Windows APIs to extract icons from the executable, like LoadImage . This can lead to a lot of extra work, however.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
EWWW, this sounds like there is no generic way to do this. I don't want the forms to have to know about the main form. Thanks for your help.
|
|
|
|
|
I never said the forms have to know about the main form. In my code snippet the Type of the main form is only used to get the namespace in which the icon is found. It's only a type reference and does not instantiate the form at all. You should read the Icon constructor documentation for more information.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Well, I've run out of things to try, so I figured I would ask here.
I've got a custom control I've been working on, but I've run into a problem. I've been able to implement design time support with a custom property editor. Everything looks fine until run-time. At run-time, the data entered at design-time doesn't show up at all.
But, the data shows up in the control perfectly at design-time. So, what's the deal?
I used Eric White's example in GDI+ Programming: Creating Custom Controls using C# Chapter 12 to create the custom modal property editor. I really don't see any difference from what I've implemented and what he has.
Any insight as to why this is happening would be greatly appreciated.
Thanks,
Zach
|
|
|
|
|
It's possible that the design-time serializer isn't capturing the property code correctly. See the documentation for the DesignerSerializationVisibilityAttribute class in the .NET Framework SDK for more information about how the property can be serialized to code.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Thanks Heath. I think that helped me figure out what the problem is (I hope so, anyways . I think it has to do with Visual Studio .Net not knowing how to turn the design-time added properties into code. But, I'm still trying to figure out how it should be fixed.
So far, I've been using a struct that contains a linked list. Each node in the linked list contains the properties for each item in the listbox(i.e. title, subtitle, theme, image, etc).
However, my instance descriptor looks like this:
return new InstanceDescriptor(typeof(Items).GetConstructor(new Type[1]{typeof(List)}), new List[1]{ myitems.itemList});
|
|
|
|
|
how do i get operating system's language?
Orcun Colak
|
|
|
|
|
Use CultureInfo.CurrentCulture to get what language is set in the regional options (for formatting dates, times, and numbers). Use CultureInfo.CurrentUICulture to get the current language pack installed and in use. The CLR sets this automatically when the application is started, but you can also set the similarily named properties on the Thread class to override the default regional and language options.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
My best guess is that C# was designed this way on purpose... with garbage collection in mind, but here's the problem.
I have a dataSet that I initialize with XML data. Let's call it ds. I then load the ds into a dataGrid (dg). However, I want to modify the appearence of the data first. So here is what I have done:
<br />
<br />
<br />
public void BindDataGrid()<br />
{<br />
DataSet temp = ds;<br />
<br />
temp.AcceptChanges();<br />
dg.DataSource = ds;<br />
dg.DataBind();<br />
}<br />
The DataGrid looks good, but it turns out that temp was apparently just a pointer to ds because ds also reflects the changes I made to temp? How do I create and use a temporary dataset without modifing the original?
|
|
|
|
|
Use Clone to copy the structure of the DataSet , but not the data. Use Copy to copy both the struct and the data. This is documented in the .NET Framework SDK for the DataSet class.
In .NET, there are no pointers, but references for reference types. Assigning a new variable an instance of an object makes that variable reference the original object. Value types work differently, however. Value types are structs, primatives (which are reflected by structs), and enumerations. Passing a value type as a parameter is always pass by value, unless you use the out or ref keywords. This is important to understand with object-oriented frameworks like .NET and Java.
Microsoft MVP, Visual C#
My Articles
|
|
|
|
|
Well!
You could copy the dataset into temp:
DataSet temp = ds.Copy();
.NET almost always creates references to objects while "copying them", so there's a unique object in memory with lots of references to it, thats what you created with temp = ds.
Anfernius
|
|
|
|
|
Any time you do an operation
a = b;
your are creating a pointer basicall making two references to a single object. An object is created in the heap, b has reference to that object, and a now has reference to that same object. It is more the rules of objects rather than a way it is done in C#.
To get a copy of the object depends on how the object is implemented. Now opening the Object Browser and searching for DataSet, when I select it I see that the Dataset object exposes ICloneable by the presence of the Clone() method.
So what you need to do is this:
a = b.Clone();
This will give you an independant clone of the object (without data as documented in the Object Browser) and allow you to change it to your hearts' content without impacting what you place in the datagrid.
Or you can do a = b.Copy() which will copy the structure and the data (as document in the Object Browser).
The object browser will give you quite alot of information on the various classes within the framework. You can run the Object Browser from the View menu option in Visual Studio. Use the binoculars icon to search for DataSet and then select the various methods to get a description of what they will do for you.
Enjoy.
______________________________
The Tao gave birth to machine language.
Machine language gave birth to the assembler.
The assembler gave birth to ten thousand languages.
Each language has its purpose, however humble.
Each language expresses the Yin and Yang of software.
Each language has its place within the Tao.
Beauty exists because we give a name to C#.
Bad exists because we give a name to COBOL.
|
|
|
|
|
I've got a class that has a Color property.
class MyClass
{
public Color Color
{
get {return color;}
set
{
color = value;
.... some other processing here ....
}
}
.... some other properties and stuff here ....
} All other members of the class serialize correctly into XML, but all I get for the Color property is a <Color /> tag output. Presumably the Color struct just doesn't serialize of it's own accord, so does anyone know a tidy way to XMLize the Color correctly?
Joel Holdsworth
Wanna give me a job over the summer?
View my online CV and Job Application[^]
|
|
|
|
|
|
Hmm... yes that looks pretty good for actually making a string representation for the Color, but how do I get that string representation to appear as the property value in the XML?
Joel Holdsworth
Wanna give me a job over the summer?
View my online CV and Job Application[^]
|
|
|
|
|
I'm developing a Windows CE .NET application.
How can I make a floating toolbar in my .NET Compact Framework application?
As alternative, can I visualize a toolbar upon the title of my form instead of inside (and on the top of) the form itself?
|
|
|
|
|
hello -
I just upgraded to VS.NET 2003 and now some of my crystal reports don't seem to work. The reports appear to run but the report viewer comes up empty. I checked all the references and I believe they are current and pointing to version 9.1.5 of the new crystal decision dlls...anyone know what the problem is?
|
|
|
|
|