C# Bitmap.Save 导出低质量图怎么弄?

Jave.Lin 2012-03-11 06:50:58
我的代码如下:

                            Rectangle cutRect = row[colIndex];
Bitmap cutBitmap = pic.Clone(cutRect, pic.PixelFormat);
Graphics g = Graphics.FromImage(cutBitmap);

ImageCodecInfo cutImageCodecInfo = ImageCodecInfo.GetImageEncoders()[0];

List<System.Drawing.Imaging.Encoder> encoderList = new List<Encoder>();
encoderList.Add(System.Drawing.Imaging.Encoder.Quality);
//encoderList.Add(System.Drawing.Imaging.Encoder.ColorDepth);
//encoderList.Add(System.Drawing.Imaging.Encoder.ChrominanceTable);

List<EncoderParameter> encoderParameter = new List<EncoderParameter>();
for (int i = 0; i < encoderList.Count; i++)
{
encoderParameter.Add(new EncoderParameter(encoderList[i], long.MinValue));
}

EncoderParameters cutEncoderParameters = new EncoderParameters(encoderList.Count);
//设置质量
cutEncoderParameters.Param = encoderParameter.ToArray();
//保存切片
string cutBmpFileName = cutBmpsPath + "\\" + rowIndex + "_" + colIndex + _sourceBitmapExtensioinName;
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;
g.DrawImage(cutBitmap, new Point());

cutBitmap.Save(cutBmpFileName, cutImageCodecInfo, cutEncoderParameters);


其中:
encoderParameter.Add(new EncoderParameter(encoderList[i], long.MinValue));
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;

两句,我都把质量设置成极底的了,怎么导出的时候,没看到有效果,切片与原图的质量效果一样。
...全文
1213 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
mrsupersky 2012-03-15
  • 打赏
  • 举报
回复
PNG 图像好像 质量没法降低的吧?
jpg是可以的。
crackdung 2012-03-15
  • 打赏
  • 举报
回复
考驗你時候,看本事了
Jave.Lin 2012-03-15
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 crackdung 的回复:]

慢慢搞吧,搞定了,項目就完成了
[/Quote]

项目急,不能慢了。

只能去找个工具实现了。

用PhotoShop的切片,也发现一个问题,如果使用限定每个切片的宽高那种方式。

如果图片的总宽高不能整除于每个切片的宽高的话,那么,他会将底部、右边、中部一行的所有切片都自适宽度,最悲剧的就是这里,他连中部的一行都会自适宽高,而且没有选项可以取消该功能。

而且没个切片不能批量操作,即使你使用Shift键来多选,也只能设置一个切片的宽、高、位置。

实在悲剧!

公司也不想为这事花钱去买工具。

悲剧!
crackdung 2012-03-14
  • 打赏
  • 举报
回复
慢慢搞吧,搞定了,項目就完成了
Jave.Lin 2012-03-14
  • 打赏
  • 举报
回复
只能说这C# 的Image的Encoder与Decoder,封装得太难用了。

找了N多资料还是没找到有用的。

CodeProject也没找到。

悲剧!

		/// <summary>
/// A quick lookup for getting image encoders
/// </summary>
private static Dictionary<string, ImageCodecInfo> encoders = null;

/// <summary>
/// A quick lookup for getting image encoders
/// </summary>
public static Dictionary<string, ImageCodecInfo> Encoders
{
//get accessor that creates the dictionary on demand
get
{
//if the quick lookup isn't initialised, initialise it
if (encoders == null)
{
encoders = new Dictionary<string, ImageCodecInfo>();
}

//if there are no codecs, try loading them
if (encoders.Count == 0)
{
//get all the codecs
foreach (ImageCodecInfo codec in ImageCodecInfo.GetImageEncoders())
{
//add each codec to the quick lookup
encoders.Add(codec.MimeType.ToLower(), codec);
}
}

//return the lookup
return encoders;
}
}

/// <summary>
/// Returns the image codec with the given mime type
/// </summary>
public static ImageCodecInfo GetEncoderInfo(string mimeType)
{
//do a case insensitive search for the mime type
string lookupKey = mimeType.ToLower();

//the codec to return, default to null
ImageCodecInfo foundCodec = null;

//if we have the encoder, get it to return
if (Encoders.ContainsKey(lookupKey))
{
//pull the codec from the lookup
foundCodec = Encoders[lookupKey];
}

return foundCodec;
}


ImageCodecInfo myImageCodecInfo = GetEncoderInfo("image/png");//ImageCodecInfo.GetImageEncoders()[0];//

EncoderParameters myEncodeParameters = new EncoderParameters(3);

EncoderParameter myEncoderParameter1 = new EncoderParameter(Encoder.Quality, 25L);
EncoderParameter myEncoderParameter2 = new EncoderParameter(Encoder.ColorDepth, 8L);//想设置为8位色深,完全无反应,NND
EncoderParameter myEncoderParameter3 = new EncoderParameter(Encoder.Compression, 50L);//压缩参数设置为0,还是不行。

myEncodeParameters.Param[0] = myEncoderParameter1;
myEncodeParameters.Param[1] = myEncoderParameter2;
myEncodeParameters.Param[2] = myEncoderParameter3;

Bitmap bmp = new Bitmap("TestPic/test.png"); // Lock the bitmap's bits.
//bmp = bmp.Clone(new Rectangle(0, 0, bmp.Width, bmp.Height), PixelFormat.Format8bppIndexed);

MemoryStream sourceMs = new MemoryStream();
bmp.Save(sourceMs, bmp.RawFormat);
byte[] sourceBytes = sourceMs.ToArray();

Bitmap newBmp = new Bitmap(bmp.Width, bmp.Height);
//newBmp.SetResolution(bmp.HorizontalResolution, bmp.VerticalResolution);
newBmp.SetResolution(72, 72);
Graphics g = Graphics.FromImage(newBmp);

g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
g.CompositingQuality = CompositingQuality.HighSpeed;
g.SmoothingMode = SmoothingMode.HighSpeed;
g.InterpolationMode = InterpolationMode.Low;

g.DrawImage(bmp, 0, 0);

//pictureBox_Image.Image = newBmp;

MemoryStream ms = new MemoryStream();
newBmp.Save(ms, myImageCodecInfo, myEncodeParameters);
Bitmap tempBmp = new Bitmap(ms);
pictureBox_Image.Image = tempBmp;
byte[] newBytes = ms.ToArray();

FileStream fs = new FileStream(
@"TestPic/test1.png",
FileMode.Create, System.Security.AccessControl.FileSystemRights.FullControl,
FileShare.None, 1024, FileOptions.Asynchronous);
fs.Write(newBytes, 0, newBytes.Length);
fs.Dispose();
fs = null;

MessageBox.Show(
"source bmp info : \r\n"+

(float)sourceBytes.Length / 1024 + "kb\r\n"+
"colorBit : " + Bitmap.GetPixelFormatSize(bmp.PixelFormat) + "\r\n"+
"isCanAlpha : " + Bitmap.IsAlphaPixelFormat(bmp.PixelFormat) + "\r\n"+
"pixel : " + bmp.PixelFormat +

"\r\n\r\ntarget bmp info : \r\n" +
(float)newBytes.Length / 1024 + "kb\r\n"+
"colorBit : " + Bitmap.GetPixelFormatSize(tempBmp.PixelFormat) + "\r\n"+
"isCanAlpha : " + Bitmap.IsAlphaPixelFormat(tempBmp.PixelFormat) + "\r\n"+
"pixel : " + tempBmp.PixelFormat);


输出为:

source bmp info :
780.8799kb
colorBit : 32
isCanAlpha : True
pixel : Format32bppArgb

target bmp info :
822.3057kb
colorBit : 32
isCanAlpha : True
pixel : Format32bppArgb

还是另求他法了。

悲剧!
Jave.Lin 2012-03-14
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 nonocast 的回复:]

生成一个新的Bitmap然后画上去

//新建一个bmp图片
System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);

//新建一个画板
System.Drawing.Graphics g = System.Drawing.G……
[/Quote]

哥,我现在纠结啊:

			ImageCodecInfo myImageCodecInfo = ImageCodecInfo.GetImageEncoders()[1];

EncoderParameters myEncodeParameters = new EncoderParameters(1);

EncoderParameter myEncoderParameter1 = new EncoderParameter(Encoder.Quality, 255L);

myEncodeParameters.Param[0] = myEncoderParameter1;

Bitmap bmp = new Bitmap("TestPic/test.png"); // Lock the bitmap's bits.

Bitmap newBmp = new Bitmap(bmp.Width, bmp.Height);
Graphics g = Graphics.FromImage(newBmp);
//以下:4项质量设置选项,可有可无,隐掉代码与应用代码都一样这么大的文件,与清晰度,难不成还与我的图片有关?
g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
g.CompositingQuality = CompositingQuality.HighSpeed;
g.SmoothingMode = SmoothingMode.HighSpeed;
g.InterpolationMode = InterpolationMode.Low;


g.DrawImage(bmp, 0, 0);

pictureBox_Image.Image = newBmp;
//这里不用codecInfo与Parameters的话,导出来的也是32位,但文件大小比原来的大;如果用上后面两个参数导出的话,又只成了24位,不带alpha通道的图片。汗。。。
newBmp.Save(@"TestPic/test1.png");//, myImageCodecInfo, myEncodeParameters);
Jave.Lin 2012-03-14
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 nonocast 的回复:]

生成一个新的Bitmap然后画上去

//新建一个bmp图片
System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);

//新建一个画板
System.Drawing.Graphics g = System.Drawing.G……
[/Quote]

我试了一下,质量是可以降了。

但,我的运行后,发现,我原来的32位带alpha通道的图片,导出后,成24位,不带alpha通道的图片了。

虽然变小了,但alpha值没了,不成喔~~~~~
nonocast 2012-03-14
  • 打赏
  • 举报
回复
生成一个新的Bitmap然后画上去

//新建一个bmp图片
System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);

//新建一个画板
System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);

//设置高质量插值法
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

//设置高质量,低速度呈现平滑程度
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

//清空画布并以透明背景色填充
g.Clear(System.Drawing.Color.Transparent);

//在指定位置并且按指定大小绘制原图片的指定部分
g.DrawImage(originalImage, new System.Drawing.Rectangle(0, 0, towidth, toheight),
new System.Drawing.Rectangle(x, y, ow, oh),
System.Drawing.GraphicsUnit.Pixel);

try
{
//以jpg格式保存缩略图
bitmap.Save(thumbnailPath, System.Drawing.Imaging.ImageFormat.Jpeg);
crackdung 2012-03-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 linjf520 的回复:]

引用 3 楼 crackdung 的回复:

想好的,請用專業的圖像控件,,,

http://ufo-crackerx.blog.163.com/blog/static/113078778201111158561961/


啊,收费的。。
[/Quote]

如果你用我說的控件肯定能解決你問題
Jave.Lin 2012-03-13
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 hoken2020856 的回复:]

好像跟Save没多大关系,你看看cutBitmap生成的一些设置吧,我以前用过clone:
C# code

RectangleF cloneRect = new RectangleF(countX * xWidth, countY * yWidth, xWidth, yWidth);
Bitmap newImage = sourceImage.Clone(cloneRect, System……
[/Quote]

不是所有的的Image对象在Save时都支持System.Drawing.Imaging.PixelFormat.Format8bppIndexed像素格式的。
Jave.Lin 2012-03-13
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 crackdung 的回复:]

想好的,請用專業的圖像控件,,,

http://ufo-crackerx.blog.163.com/blog/static/113078778201111158561961/
[/Quote]

啊,收费的。。
hoken2020856 2012-03-13
  • 打赏
  • 举报
回复
好像跟Save没多大关系,你看看cutBitmap生成的一些设置吧,我以前用过clone:

RectangleF cloneRect = new RectangleF(countX * xWidth, countY * yWidth, xWidth, yWidth);
Bitmap newImage = sourceImage.Clone(cloneRect, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);//这里指定Format
crackdung 2012-03-13
  • 打赏
  • 举报
回复
想好的,請用專業的圖像控件,,,

http://ufo-crackerx.blog.163.com/blog/static/113078778201111158561961/
Jave.Lin 2012-03-13
  • 打赏
  • 举报
回复
Help~~~~~~~

Graphics thumbnailBmpGraphics = Graphics.FromImage(thumbnailBmp);
//设置切片质量,并重绘
thumbnailBmpGraphics.PixelOffsetMode = PixelOffsetMode.HighSpeed;
thumbnailBmpGraphics.CompositingQuality = CompositingQuality.HighSpeed;
thumbnailBmpGraphics.SmoothingMode = SmoothingMode.HighSpeed;
thumbnailBmpGraphics.InterpolationMode = InterpolationMode.Low;
thumbnailBmpGraphics.DrawImage(thumbnailBmp, new Point());


悲了个剧啊。

咋设置一系列的高速度,低质量之后。

thumbnailBmp.Save出来的还是这么大啊?咋回事?
Jave.Lin 2012-03-12
  • 打赏
  • 举报
回复
oh my god~

木有人了。

111,094

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧