Хорошо, первая проблема в том, что изменение размера изображения на любом языке занимает немного времени. Итак, как вы поддерживаете тысячи клиентов? Мы кешируем его, поэтому вам нужно сгенерировать изображение только один раз. В следующий раз, когда кто-то запросит это изображение, проверьте, было ли оно уже сгенерировано, если оно только что вернуло это. Если у вас есть несколько серверов приложений, вам нужно будет кэшировать данные в центральной файловой системе, чтобы увеличить коэффициент попаданий в кэш и уменьшить объем необходимого вам пространства.
Для правильного кэширования необходимо использовать предсказуемое соглашение об именах, которое учитывает все возможные способы отображения изображения, например, использовать что-то вроде myimage_blurred_320x200.jpg, чтобы сохранить изображение в формате JPEG, которое было размыто и масштабировано до 300. ширина и высота 200 и т. д.
Другой подход заключается в размещении вашего сервера изображений за прокси-сервером таким образом, чтобы вся логика кэширования выполнялась для вас автоматически, а ваши изображения обслуживались быстрым собственным веб-сервером.
Вы не сможете обслуживать миллионы изображений с измененным размером любым другим способом. Это то, как карты Google и Bing делают это, они предварительно генерируют все изображения, которые им нужны для мира, в различных предустановленных экстентах, чтобы они могли обеспечить адекватную производительность и иметь возможность возвращать предварительно созданные статические изображения.
Если php слишком медленный, вам следует рассмотреть возможность использования 2D-графических библиотек из Java или .NET, поскольку они очень богаты и могут поддерживать все ваши требования. Чтобы получить представление о графическом 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;
}