元の画像を取得して、3つの異なるズームスケール-> 16倍、10倍、4倍にサイズ変更する関数を作成しました。理解を深めるために、この段落を読み続けてください。元の画像が1000x1000だとしましょう。1倍ズームでの寸法は50x50になることを宣言します。つまり、4倍ズームは200x200、10倍ズームは500x500、16倍ズームは800x800になります。したがって、私の関数は、元の1000x1000を800x800に、次に500x500に、次に200x200にサイズ変更する必要があります。私はこれを正常に実行し、私の質問はメモリ使用量に関するものであることに注意してください。
以下に2つの方法があります。どちらの方法も機能しますが、一方が他方よりも約3x / 4倍多くのメモリを使用して大量のメモリ使用量を膨らませます...3つの画像のそれぞれのサイズを変更しないため、最初の方法よりも大幅に高速に読み込まれるため、2番目の方法の方が好きです。元の画像からではなく、以前にサイズ変更された画像からサイズを変更します。
注:メモリ使用量を測定するためにXcodeInstrumentsを使用しています。ImageResizerクラスには、画像のサイズを変更する「サイズ変更」と呼ばれる関数が含まれています。
方法1.)
public List<UIImage> InitImageList_BFObjects ( UIImage image, SizeF frameSize )
{
List<UIImage> listOfImages = new List<UIImage>();
for ( int i = 0; i < 3; i++ )
{
if ( i == 0 )
zoomScale = 16f;
else if ( i == 1 )
zoomScale = 10f;
else// if ( i == 2 )
zoomScale = 4f;
Resizer = new ImageResizer(image);
Resizer.Resize(frameSize.Width * zoomScale, frameSize.Height * zoomScale);
UIImage resizedImage = Resizer.ModifiedImage;
listOfImages.Insert(0, resizedImage);
}
return listOfImages;
}
方法1は機能し、メモリ使用量はごくわずかです。私はこれを約20枚の画像のグループで実行しました。これがロードされた後、私のアプリには約14MBのメモリ使用量がありました(Xcodes Instrumentsを使用してメモリ使用量を調べます)
方法2.)
public List<UIImage> InitImageList_BFObjects ( UIImage image, SizeF frameSize )
{
List<UIImage> listOfImages = new List<UIImage>();
for ( int i = 0; i < 3; i++ )
{
if ( i == 0 )
zoomScale = 16f;
else if ( i == 1 )
zoomScale = 10f;
else// if ( i == 2 )
zoomScale = 4f;
if ( listOfImages.Count == 0 )
{
Resizer = new ImageResizer(image);
Resizer.Resize(frameSize.Width * zoomScale, frameSize.Height * zoomScale);
UIImage resizedImage = Resizer.ModifiedImage;
listOfImages.Insert(0, resizedImage);
}
else
{
// THIS LINE CONTAINS THE MAIN DIFFERENCE BETWEEN METHOD 1 AND METHOD 2
// Notice how it resizes from the most recent image from listOfImages rather than the original image
Resizer = new ImageResizer(listOfImages[0]);
Resizer.Resize(frameSize.Width * zoomScale, frameSize.Height * zoomScale);
UIImage resizedImage = Resizer.ModifiedImage;
listOfImages.Insert(0, resizedImage);
}
}
return listOfImages;
}
方法2は機能しますが、メモリ使用量は急上昇します。私はこれを約20枚の画像の同じグループで実行しました。これがロードされた後、私のアプリのメモリ使用量は60MBを超えました(Xcodes Instrumentsを使用してメモリ使用量を調べます)なぜメモリ使用量が非常に高いのですか?記憶がロケットに飛ぶ原因となる方法2についてはどうですか?変数が適切にクリーンアップされていないようです
*追加情報、ImageResizerクラス* *
ImageResizerクラスから不要な関数を切り取り、名前を「ImageResizer_Abridged」に変更しました。誤って必要なものを切り取らないようにするために、このクラスの使用に切り替えました。
public class ImageResizer_Abridged
{
UIImage originalImage = null;
UIImage modifiedImage = null;
public ImageResizer_Abridged ( UIImage image )
{
this.originalImage = image;
this.modifiedImage = image;
}
/// <summary>
/// strech resize
/// </summary>
public void Resize( float width, float height )
{
UIGraphics.BeginImageContext( new SizeF( width, height ) );
//
modifiedImage.Draw( new RectangleF( 0,0, width, height ) );
modifiedImage = UIGraphics.GetImageFromCurrentImageContext();
//
UIGraphics.EndImageContext();
}
public UIImage OriginalImage
{
get
{
return this.originalImage;
}
}
public UIImage ModifiedImage
{
get
{
return this.modifiedImage;
}
}
}
この問題を示す簡略化されたテストプロジェクトを作成しました*
プロジェクトへのドロップボックスリンクは次のとおりです: https ://www.dropbox.com/s/4w7d87nn0aafph9/TestMemory.zip
これが証拠としてのメソッド1のXcodeInstrumentsスクリーンショットです(9 mbのメモリ使用量):http: //i88.photobucket.com/albums/k194/lampshade9909/AllImagesResizedFromOriginalImage_zps585228c6.jpg
証拠としてホットなメソッド2のXcodeInstruments画面は次のとおりです(55 mbのメモリ使用量):http: //i88.photobucket.com/albums/k194/lampshade9909/SignificantIncreaseInMemoryUsage_zps19034bad.jpg
以下は、テストプロジェクトを実行するために必要なコードブロックです
// Initialize My List of Images
ListOfImages = new List<UIImage>();
for ( int i = 0; i < 30; i++ )
{
// Create a UIImage Containing my original Image
UIImage originalImage = UIImage.FromFile ("b2Bomber.png");
float newWidth = 100f;
float newHeight = 40f;
float zoomScale;
float resizedWidth, resizedHeight;
UIImage resizedImage1;
UIImage resizedImage2;
// Basically, I want to take the originalImage Image and resize it twice.
// Method 1.) Resize the originalImage and save it as ResizedImage1. Resize the originalImage and save it as ResizedImage2. We're finished!
// Method 2.) Resize the originalImage and save it as ResizedImage1. Resize ResizedImage1 and save it as ResizedImage2. We're finished!
// The pro to Method 1 is that we get the best possible quaility on all resized images. The con is, this takes a long time if we're doing dozens of very large images
// The pro to Method 2 is that it's faster than Method 1. This is why I want to use Method 2, it's speed. But it has a HUGE con, it's memory usage.
// Please run this project on an iPad connected to XCodes Instruments to monitor memory usage and see what I mean
zoomScale = 10f;
resizedWidth = newWidth*zoomScale;
resizedHeight = newHeight*zoomScale;
UIGraphics.BeginImageContext( new SizeF( resizedWidth, resizedHeight ) );
originalImage.Draw( new RectangleF( 0, 0, resizedWidth, resizedHeight ) );
resizedImage1 = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
zoomScale = 4f;
resizedWidth = newWidth*zoomScale;
resizedHeight = newHeight*zoomScale;
UIGraphics.BeginImageContext( new SizeF( resizedWidth, resizedHeight ) );
// Run this project on an iPad and examine the memory usage in XCode's Instruments.
// The Real Memory Usage will be aroud 9 MB.
// Uncomment this "originalImage.Draw" line to see this happening, make sure to comment out the "resizedImage1.Draw" line
// originalImage.Draw( new RectangleF( 0, 0, resizedWidth, resizedHeight ) );
// Run this project on an iPad and examine the memory usage in XCode's Instruments.
// The Real Memory Usage will be aroud 55 MB!!
// My question is, why does the memory sky rocket when doing this, and how can I prevent the memory from sky rocketing??
// My App requires me to resize around a hundred images and I want to be able to resize an already resized image (like in this example) without the memory usage sky rocketing like this...
// Uncomment this "resizedImage1.Draw" line to see this happening, make sure to comment out the "originalImage.Draw" line
resizedImage1.Draw( new RectangleF( 0, 0, resizedWidth, resizedHeight ) );
resizedImage2 = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
// Add my resized images to the list of Images
ListOfImages.Add (resizedImage1);
ListOfImages.Add (resizedImage2);
}