昔(かなり昔)作ったコードですが、.jpg 画像を FileUpload を使ってアップロードし、指定したサイズの Thumnail を作るコードを紹介しておきます。参考になれば幸いです。
MakeThumb メソッドを見てください。画像ファイルのバイト列を受けて、指定されたサイズに縮小し、結果をバイト列で返します。3 つオーバーロードがありますが、違いはコメントを見てください。
using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Drawing;
using System.Configuration;
using System.Drawing.Drawing2D;
// 2008-12-17
// 縮小したイメージのギザギザを軽減するために Graphics.InterpolationMode を
// 使用するようにした。その場合、縮小に Graphics.DrawImage メソッドを使う必
// 要があり、GetThumbnailImage メソッド、Bitmap コンストラクタを使用している
// 部分は変更した。
public class ImageUtils
{
const int sizeThumb = 69; // thumbimage のサイズ(縦横同じ)
const int sizeLarge = 400; // largerimage のサイズ(横幅) 2008-3-22 350 から 400 に変更。
public static int uploadImage(string title, int albumid, Stream data)
{
// 自分以外もアップロードできるような場合は、ファイルサイズの制限をすべき
// (今回はしていない)。
int length = Convert.ToInt32(data.Length);
byte[] origImageData = new byte[length];
data.Read(origImageData, 0, length);
SqlConnection connection =
new SqlConnection(ConfigurationManager.ConnectionStrings["userConnectionString"].ConnectionString);
SqlCommand command =
new SqlCommand("INSERT INTO Images (title, origimage, largeimage, thumbimage, album) " +
"VALUES ( @title, @origimage, @largeimage, @thumbimage, @albumid); select SCOPE_IDENTITY()", connection);
SqlParameter param0 = new SqlParameter("@title", SqlDbType.VarChar, 50);
param0.Value = title;
command.Parameters.Add(param0);
SqlParameter param1 = new SqlParameter("@origimage", SqlDbType.Image);
param1.Value = origImageData;
command.Parameters.Add(param1);
SqlParameter param2 = new SqlParameter("@largeimage", SqlDbType.Image);
param2.Value = MakeThumb(origImageData, sizeLarge);
command.Parameters.Add(param2);
SqlParameter param3 = new SqlParameter("@thumbimage", SqlDbType.Image);
param3.Value = MakeThumb(origImageData, sizeThumb, sizeThumb);
command.Parameters.Add(param3);
SqlParameter param4 = new SqlParameter("@albumid", SqlDbType.Int);
param4.Value = albumid;
command.Parameters.Add(param4);
object result;
try
{
connection.Open();
result = command.ExecuteScalar();
}
finally
{
connection.Close();
}
if (result != null)
{
return System.Convert.ToInt32(result);
}
else
{
return 0;
}
}
// sizeThumb で指定されたサイズのサムネイルを作る。
// オリジナルの縦横比は保たれる(高さ or 幅のどちらか大きい方が sizeThumb のサイズになる)。
public static byte[] MakeThumb(byte[] fullsize)
{
Image iOriginal, iThumb;
int targetH, targetW;
iOriginal = Image.FromStream(new MemoryStream(fullsize));
if (iOriginal.Height > iOriginal.Width)
{
targetH = sizeThumb;
// オリジナルのコードに誤りあり。割り算は double で計算しないとゼロになる。
// このメソッドは使っていないので誤りに気がつかなかった。double のキャストを追記。
targetW = Convert.ToInt32((double)iOriginal.Width * ((double)sizeThumb / (double)iOriginal.Height));
}
else
{
targetW = sizeThumb;
// ここも誤り。double のキャストを追記。
targetH = Convert.ToInt32((double)iOriginal.Height * ((double)sizeThumb / (double)iOriginal.Width));
}
// 2008-12-17: ギザギザ軽減のため変更。以下を削除して
//iThumb = iOriginal.GetThumbnailImage(targetW, targetH, null, System.IntPtr.Zero);
// 以下を追加
iThumb = new Bitmap(targetW, targetH);
Graphics g = Graphics.FromImage(iThumb);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
Rectangle srcRect = new Rectangle(0, 0, iOriginal.Width, iOriginal.Height);
g.DrawImage(iOriginal, new Rectangle(0, 0, targetW, targetH), srcRect, GraphicsUnit.Pixel);
MemoryStream m = new MemoryStream();
iThumb.Save(m, System.Drawing.Imaging.ImageFormat.Jpeg);
return m.GetBuffer();
}
// 指定のサイズのサムネイルを作る。
// 縦横で縮小率が異なる場合、変形されないよう大きい方をトリミングしてから縮小する。
public static byte[] MakeThumb(byte[] fullsize, int newwidth, int newheight)
{
Image iOriginal, iThumb;
double scaleH, scaleW;
// トリミングの範囲を指定する。
Rectangle srcRect = new Rectangle();
iOriginal = Image.FromStream(new MemoryStream(fullsize));
// ここも誤り。右辺は double で計算要。オリジナルのサイズが大きいので誤差が小さく、
// かつ画像が 69 x 69 と小さいので気がつかなかったが、変形していた。
scaleH = (double)iOriginal.Height / (double)newheight;
scaleW = (double)iOriginal.Width / (double)newwidth;
if (scaleH == scaleW) // 縦横の縮小率が同じ → トリミングなし
{
srcRect.Width = iOriginal.Width;
srcRect.Height = iOriginal.Height;
srcRect.X = 0;
srcRect.Y = 0;
}
else if ((scaleH) > (scaleW)) // 縮小率が、縦 > 横 → 縦のみトリミング
{
srcRect.Width = iOriginal.Width;
// ここはキャストは必要ないはずだが念のため。
srcRect.Height = Convert.ToInt32((double)newheight * scaleW);
srcRect.X = 0;
// ここは整数の計算でも可(Convert.ToInt32() は不用)。
srcRect.Y = (iOriginal.Height - srcRect.Height) / 2;
}
else // 縮小率が、縦 < 横 → 横のみトリミング
{
// ここはキャストは必要ないはずだが念のため。
srcRect.Width = Convert.ToInt32((double)newwidth * scaleH);
srcRect.Height = iOriginal.Height;
// ここは整数の計算でも可(Convert.ToInt32() は不用)。
srcRect.X = (iOriginal.Width - srcRect.Width) / 2;
srcRect.Y = 0;
}
iThumb = new Bitmap(newwidth, newheight);
Graphics g = Graphics.FromImage(iThumb);
// 2008-12-17: ギザギザ軽減のため追加。
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(iOriginal, new Rectangle(0, 0, newwidth, newheight), srcRect, GraphicsUnit.Pixel);
MemoryStream m = new MemoryStream();
iThumb.Save(m, System.Drawing.Imaging.ImageFormat.Jpeg);
return m.GetBuffer();
}
// 幅のみ指定してサムネイルを作る。高さは幅と同じ縮小率で縮小。
public static byte[] MakeThumb(byte[] fullsize, int maxwidth)
{
Image iOriginal, iThumb;
double scale;
iOriginal = Image.FromStream(new MemoryStream(fullsize));
if (iOriginal.Width > maxwidth)
{
// オリジナルのコードはここに誤り(右辺が整数型)があり、newheight が正しく計算されず
// 画像が変形してしまった。キャスト (double) を追加して修正。
scale = (double)iOriginal.Width / (double)maxwidth;
int newheight = Convert.ToInt32((double)iOriginal.Height / scale);
// 2008-12-17: ギザギザ軽減のため変更。以下を削除して
//iThumb = new Bitmap(iOriginal, maxwidth, newheight);
// 以下を追加
iThumb = new Bitmap(maxwidth, newheight);
Graphics g = Graphics.FromImage(iThumb);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
Rectangle srcRect = new Rectangle(0, 0, iOriginal.Width, iOriginal.Height);
g.DrawImage(iOriginal, new Rectangle(0, 0, maxwidth, newheight), srcRect, GraphicsUnit.Pixel);
MemoryStream m = new MemoryStream();
iThumb.Save(m, System.Drawing.Imaging.ImageFormat.Jpeg);
return m.GetBuffer();
}
else
{
return fullsize;
}
}
}
オリジナル画像ファイルのバイト列は、FileUpload.FileContent プロパティを使って Stream オブジェクトを取得し、以下のようなコード (data が取得した Stream) でバイト列に変換してみてください。
int length = Convert.ToInt32(data.Length);
byte[] origImageData = new byte[length];
data.Read(origImageData, 0, length);
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/08/25 07:27
退会済みユーザー
2021/08/25 07:32
2021/08/25 07:45