我有一个简单的restapi内置在coldfusion11中,允许我们的供应商更新产品信息。它们发送的大多数数据(大约30个属性)都是简单的值—字符串和数字。一个属性是表示图像文件的base64编码字符串。restapi更新数据库中的简单数据值,然后读取图像并将其调整为适合在网站上使用的4个大小。我注意到,有时供应商会发送带有一些请求(20mb+)的大图像,这些请求通常会在 ImageReadBase64()
函数被调用。我们在这个服务器上运行了其他的web应用程序,似乎处理这些图像时被锁定的内存也会导致这些应用程序出现问题。我正在尝试找出代码中是否有什么可以减少这些问题的方法,即使是找到一种方法,如果图像“太大”(超过一定大小),就不处理它们。以下是运行以处理图像的所有代码:
public struct function getDimensionsToEnlarge(
required numeric imageWidth,
required numeric imageHeight,
required numeric minWidth,
required numeric minHeight
) {
LOCAL.Dimensions={
width=-1,
height=-1
};
if ( ARGUMENTS.minHeight > 0
&& ARGUMENTS.minWidth > 0
&& ARGUMENTS.imageHeight < ARGUMENTS.minHeight
&& ARGUMENTS.imageWidth < ARGUMENTS.minWidth
) {
LOCAL.Dimensions.width=ARGUMENTS.minWidth;
LOCAL.Dimensions.height=ARGUMENTS.minHeight;
}
return LOCAL.Dimensions;
}
public struct function getDimensionsToShrink(
required numeric imageWidth,
required numeric imageHeight,
required numeric maxWidth,
required numeric maxHeight
) {
LOCAL.Dimensions={
width=-1,
height=-1
};
if ( ARGUMENTS.maxHeight > 0
&& ARGUMENTS.maxWidth > 0
&& ( ARGUMENTS.imageHeight > ARGUMENTS.maxHeight
|| ARGUMENTS.imageWidth > ARGUMENTS.maxWidth
)
) {
LOCAL.Dimensions.width=ARGUMENTS.maxWidth;
LOCAL.Dimensions.height=ARGUMENTS.maxHeight;
}
return LOCAL.Dimensions;
}
public struct function getDimensionsToFit(
required numeric imageWidth,
required numeric imageHeight,
required numeric minWidth,
required numeric minHeight,
required numeric maxWidth,
required numeric maxHeight
) {
LOCAL.Dimensions={
width=-1,
height=-1
};
LOCAL.Dimensions =
getDimensionsToEnlarge(
imageHeight=ARGUMENTS.imageHeight,
imageWidth=ARGUMENTS.imageWidth,
minWidth=ARGUMENTS.minWidth,
minHeight=ARGUMENTS.minHeight
);
if (LOCAL.Dimensions.width < 0 && LOCAL.Dimensions.height < 0)
LOCAL.Dimensions =
getDimensionsToShrink(
imageHeight=ARGUMENTS.imageHeight,
imageWidth=ARGUMENTS.imageWidth,
maxWidth=ARGUMENTS.maxWidth,
maxHeight=ARGUMENTS.maxHeight
);
return LOCAL.Dimensions;
}
public any function scale(
required any image,
string action="fit",
numeric minWidth=-1,
numeric minHeight=-1,
numeric maxWidth=-1,
numeric maxHeight=-1
) {
LOCAL.Dimensions={
width=-1,
height=-1
};
LOCAL.Image=Duplicate(ARGUMENTS.image);
switch (ARGUMENTS.action) {
case "shrink":
LOCAL.Dimensions =
getDimensionsToShrink(
imageHeight=LOCAL.Image.getHeight(),
imageWidth=LOCAL.Image.getWidth(),
maxWidth=ARGUMENTS.maxWidth,
maxHeight=ARGUMENTS.maxHeight
);
break;
case "enlarge":
LOCAL.Dimensions =
getDimensionsToEnlarge(
imageHeight=LOCAL.Image.getHeight(),
imageWidth=LOCAL.Image.getWidth(),
minWidth=ARGUMENTS.minWidth,
minHeight=ARGUMENTS.minHeight
);
break;
default:
LOCAL.Dimensions =
getDimensionsToFit(
imageHeight=LOCAL.Image.getHeight(),
imageWidth=LOCAL.Image.getWidth(),
minWidth=ARGUMENTS.minWidth,
minHeight=ARGUMENTS.minHeight,
maxWidth=ARGUMENTS.maxWidth,
maxHeight=ARGUMENTS.maxHeight
);
break;
}
if (LOCAL.Dimensions.width > 0 && LOCAL.Dimensions.height > 0) {
ImageSetAntialiasing(LOCAL.Image, "on");
ImageScaleToFit(
LOCAL.Image,
LOCAL.Dimensions.width,
LOCAL.Dimensions.height
);
}
return LOCAL.Image;
}
public void function createLargeThumbnail(required any image) {
ImageWrite(
scale(image=ARGUMENTS.image, maxHeight=500, maxWidth=700),
getLargeImagePath(),
0.75,
true
);
return;
}
public void function createMediumThumbnail(required any image) {
ImageWrite(
scale(image=ARGUMENTS.image, maxHeight=300, maxWidth=300),
getMediumImagePath(),
0.75,
true
);
return;
}
public void function createSmallThumbnail(required any image) {
ImageWrite(
scale(image=ARGUMENTS.image, maxHeight=50, maxWidth=50),
getSmallImagePath(),
0.75,
true
);
return;
}
public void function createMobileThumbnail(required any image) {
ImageWrite(
scale(image=ARGUMENTS.image, maxHeight=50, maxWidth=300),
getMobileImagePath(),
0.75,
true
);
return;
}
public void function createProductThumbnails(required any image) {
createLargeThumbnail(argumentCollection=ARGUMENTS);
createMediumThumbnail(argumentCollection=ARGUMENTS);
createSmallThumbnail(argumentCollection=ARGUMENTS);
createMobileThumbnail(argumentCollection=ARGUMENTS);
return;
}
createProductThumbnails(ImageReadBase64(ARGUMENTS.ImageUpload));
我需要做些什么来启动垃圾回收吗?
谢谢你的帮助!
1条答案
按热度按时间vulvrdjw1#
你在打电话吗
scale()
四次(每次createXXXThumbnail()
),有效地将内存使用率提高了四倍,因为duplicate()
通过参数传递的图像对象。你也打电话给本地人ImageScaleToFit()
使用昂贵的默认插值四次,这可能会在内部创建另一个字节数组。因此,看起来无辜的20MB在处理过程中很容易膨胀到160MB甚至更多。