好的,第一个问题是使用任何语言调整图像大小需要一点处理时间。那么,您如何支持成千上万的客户呢?我们会缓存它,因此您只需生成一次图像。下次有人请求该图像时,检查它是否已经生成,如果它刚刚返回。如果您有多个应用服务器,那么您需要缓存到中央文件系统以提高缓存命中率并减少所需的空间量。
为了正确缓存,您需要使用可预测的命名约定,该约定考虑到您希望图像显示的所有不同方式,即使用 myimage_blurred_320x200.jpg 之类的东西来保存已模糊并调整大小为 300 宽度和 200 的 jpeg高度等
另一种方法是将您的图像服务器放在代理服务器后面,这样所有缓存逻辑都会自动为您完成,并且您的图像由快速的本地 Web 服务器提供服务。
您将无法以任何其他方式提供数百万张调整大小的图像。这就是 Google 和 Bing 地图的做法,它们以不同的预设范围预先生成世界所需的所有图像,因此它们可以提供足够的性能并能够返回预先生成的静态图像。
如果 php 太慢,您应该考虑使用 Java 或 .NET 的 2D 图形库,因为它们非常丰富并且可以支持您的所有要求。为了了解 Graphics API,这里有一个 .NET 中的方法,它可以将任何图像的大小调整为指定的新宽度或高度。如果您省略高度或宽度,它将调整大小以保持正确的纵横比。注意 图像可以从 JPG、GIF、PNG 或 BMP 创建:
// Creates a re-sized image from the SourceFile provided that retails the same aspect ratio of the SourceImage.
// - If either the width or height dimensions is not provided then the resized image will use the
// proportion of the provided dimension to calculate the missing one.
// - If both the width and height are provided then the resized image will have the dimensions provided
// with the sides of the excess portions clipped from the center of the image.
public static Image ResizeImage(Image sourceImage, int? newWidth, int? newHeight)
{
bool doNotScale = newWidth == null || newHeight == null; ;
if (newWidth == null)
{
newWidth = (int)(sourceImage.Width * ((float)newHeight / sourceImage.Height));
}
else if (newHeight == null)
{
newHeight = (int)(sourceImage.Height * ((float)newWidth) / sourceImage.Width);
}
var targetImage = new Bitmap(newWidth.Value, newHeight.Value);
Rectangle srcRect;
var desRect = new Rectangle(0, 0, newWidth.Value, newHeight.Value);
if (doNotScale)
{
srcRect = new Rectangle(0, 0, sourceImage.Width, sourceImage.Height);
}
else
{
if (sourceImage.Height > sourceImage.Width)
{
// clip the height
int delta = sourceImage.Height - sourceImage.Width;
srcRect = new Rectangle(0, delta / 2, sourceImage.Width, sourceImage.Width);
}
else
{
// clip the width
int delta = sourceImage.Width - sourceImage.Height;
srcRect = new Rectangle(delta / 2, 0, sourceImage.Height, sourceImage.Height);
}
}
using (var g = Graphics.FromImage(targetImage))
{
g.SmoothingMode = SmoothingMode.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(sourceImage, desRect, srcRect, GraphicsUnit.Pixel);
}
return targetImage;
}