рдХрдИ рд╢рд╛рдпрдж рдкрд╣рд▓реЗ рд╕реЗ рд╣реА OutOfMemoryError рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рдордирд╛ рдХрд░ рд░рд╣реЗ рдереЗ рдФрд░ рдПрдХ рдХрд╛рдлреА рд╕рдордЭрджрд╛рд░ рдкреНрд░рджрд░реНрд╢рди рдХрд░рдиреЗ рд╡рд╛рд▓реЗ
рдмрд┐рдЯрдореИрдкреНрд╕ рдХреЛ рдХреБрд╢рд▓рддрд╛ рд╕реЗ рдореИрдиреБрдЕрд▓ рдХрд░ рдкрд╛рдПред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдЖрдк рдЕрднреА рддрдХ рдореИрдиреБрдЕрд▓ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЕрдкрдиреА рдмрд╛рдЗрдХ рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдХрд░рдиреЗ рдореЗрдВ рдХрд╛рдордпрд╛рдм рдирд╣реАрдВ рд╣реБрдП рд╣реИрдВ, рддреЛ рдореИрдВ рдЕрдкрдирд╛ рдЯрд░реНрдирдХреА рд╕рдорд╛рдзрд╛рди рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдХреЗ рд╕рд╛рде рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реВрдВ рдЬреЛ рдЖрдкрдХреЛ рдкреНрд░рд╛рдкреНрдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ:
- рдмрд┐рдЯрдореИрдк рдФрд░ рдмрд╛рдЗрдЯ рдореЗрдВ [] рдкреНрд░рд╛рд░реВрдк
- рдЕрдиреБрдкрд╛рдд рдХреЛ рдмрдирд╛рдП рд░рдЦрддреЗ рд╣реБрдП рдХрдо рдХрд┐рдпрд╛ рдЧрдпрд╛
- рдлрд╕рд▓ рдХреЗ рд╕рд╛рде рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЪреМрдбрд╝рд╛рдИ x рдКрдБрдЪрд╛рдИ рддрдХ рдХрдо рд╣реЛ рдЬрд╛рддреА рд╣реИ
- 2 рдЬреА рдХреЗ рд▓рд┐рдП рдЕрдиреБрдХреВрд▓рд┐рдд
- рд╣рдореЗрд╢рд╛ рд╕рд╣реА рдУрд░рд┐рдПрдВрдЯреЗрд╢рди рдореЗрдВ (EXIF рдУрд░рд┐рдПрдВрдЯреЗрд╢рди рджрд┐рдпрд╛ рдЧрдпрд╛)
рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВImageManager im = new ImageManager(ctx, 100, 100); Bitmap bm = im.setIsScale(true) .setIsResize(true) .setIsCrop(true) .getFromFile(myUri.toString());
OutOfMemoryError
рдпрд╣ рддреНрд░реБрдЯрд┐ рдХреНрдпреЛрдВ рд╣реЛ рд░рд╣реА рд╣реИ? рдмрд╛рдд рдпрд╣ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд▓рд┐рдП рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд╕реАрдорд┐рдд рдорд╛рддреНрд░рд╛ рдореЗрдВ рдореЗрдореЛрд░реА (рдвреЗрд░ рдХрд╛ рдЖрдХрд╛рд░) рдЖрд╡рдВрдЯрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, 16mb, 24mb рдФрд░ рдЙрдЪреНрдЪрддрд░ред рдЖрдзреБрдирд┐рдХ рдЙрдкрдХрд░рдгреЛрдВ рдореЗрдВ рдЖрдорддреМрд░ рдкрд░ 24mb рдФрд░ рдЙрдЪреНрдЪрддрд░ рд╣реЛрддреЗ рд╣реИрдВ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрди рдореВрд▓реНрдпреЛрдВ рдХреЛ рдЬрд▓реНрджреА рд╕реЗ "рдЦрд╛рдпрд╛" рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред
рдХреНрдпрд╛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕реНрдореГрддрд┐ рдХреЛ рдЕрд╡рд╢реЛрд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ? рдЗрд╕рдХрд╛ рдЙрддреНрддрд░ рдмрд┐рдЯрдореИрдк рд╡рд░реНрдЧ рдореЗрдВ рд╣реИ, рдЬреЛ рдЖрдо рддреМрд░ рдкрд░ рдкреНрд░рддреНрдпреЗрдХ рдкрд┐рдХреНрд╕реЗрд▓ рдХреЗ рд▓рд┐рдП 2 рдпрд╛ 4 рдмрд╛рдЗрдЯреНрд╕ рдХрд╛ рдЙрдкрднреЛрдЧ рдХрд░рддрд╛ рд╣реИ (рдЫрд╡рд┐ рдХреЗ рдмрд┐рдЯ рдЖрдХрд╛рд░ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ - 16 рдмрд┐рдЯ рдЖрд░рдЬреАрдмреА_555 рдпрд╛ 32 рдмрд┐рдЯ рдПрдЖрд░рдЬреАрдмреА_888)ред рдЖрдЗрдП рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ 5 рдореЗрдЧрд╛рдкрд┐рдХреНрд╕реЗрд▓ рдХреИрдорд░реЗ рдХреЗ рд╕рд╛рде рдПрдХ рдЫрд╡рд┐ рд╢реЙрдЯ рд╡рд╛рд▓реЗ рдмрд┐рдЯрдореИрдк рдХрд┐рддрдирд╛ рдЦрд╛рдПрдВрдЧреЗред
4: 3 рдХреЗ рдПрдХ рдкрд╣рд▓реВ рдЕрдиреБрдкрд╛рдд рдХреЗ рд╕рд╛рде, 2583 x 1936 рдХреЗ рдкрдХреНрд╖реЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рдЫрд╡рд┐ рдкреНрд░рд╛рдкреНрдд рдХреА рдЬрд╛рдПрдЧреАред RGB_555 рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ, рд╣рдорд╛рд░рд╛ рдмрд┐рдЯрдореИрдк 2583 * 1936 * 2 = 9.54 MB рд▓реЗ рдЬрд╛рдПрдЧрд╛ (рдЗрд╕рдХреЗ рдмрд╛рдж рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ MB-2 20 рдмрд╛рдЗрдЯреНрд╕ рдХреА рд╢рдХреНрддрд┐ рд╣реИ), рдФрд░ ARGB_888 рдореЗрдВ 2 рдмрд╛рд░ред рдЕрдзрд┐рдХ - 19 рдПрдордмреА рд╕реЗ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХред рдЕрдзрд┐рдХ рдореЗрдЧрд╛рдкрд┐рдХреНрд╕реЗрд▓ рд╡рд╛рд▓реЗ рдХреИрдорд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕реЛрдЪрдирд╛ рдбрд░рд╛рд╡рдирд╛ рд╣реИред
рд╕рдорд╛рдзрд╛рди рдЫреЛрдЯрд╛ рдФрд░ рд╕реНрдкрд╖реНрдЯ рд╣реИред
1) рдмрд┐рдЯрдореИрдкрдлреИрдХреНрдЯрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ред рдерд░реНрдб рдкреИрд░рд╛рдореАрдЯрд░ рдирдП рдмрд┐рдЯрдореИрдкрдлреИрдХреНрдЯреНрд░реАрдСрдХреНрд╢рдВрд╕ () рдХреЗ рд╕рд╛рде рдлрдВрдХреНрд╢рди рдХрд╛ рдкреНрд░рдпреЛрдЧ рдХрд┐рдпрд╛ рдЧрдпрд╛, рдЬрд┐рд╕рдореЗрдВ inJustDecodeBounds = рд╕рдЪ рд╣реИ, рд╣рдореЗрдВ рдкрд┐рдХреНрд╕рд▓ рдореЗрдВ рдХреЗрд╡рд▓ рдЫрд╡рд┐ рдЖрдпрд╛рдореЛрдВ рд╡рд╛рд▓реЗ рдмрд┐рдЯрдореИрдк рдкреНрд░рд╛рдкреНрдд рд╣реЛрддреЗ рд╣реИрдВ рдФрд░ рд╕реНрд╡рдпрдВ рдкрд┐рдХреНрд╕реЗрд▓ рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред
2) рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ рдХрд┐ рд╣рдореЗрдВ рдХрд┐рддрдиреА рдмрд╛рд░ рдЫрд╡рд┐ рдХреЛ рдХрдо рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рд╣рдореЗрдВ рдЖрдпрд╛рдореЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛред
3) рдЗрд╕ рдорд╛рди рдХреЛ BitmapFactory.Options рдЖрд╡реГрддреНрддрд┐ рдХреЗ рдирдореВрдирд╛ рдХреНрд╖реЗрддреНрд░ рдореЗрдВ рдЕрд╕рд╛рдЗрди рдХрд░реЗрдВ рдФрд░ рдлрд┐рд░ рд╕реЗ BitmapFactory.decodeStream рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВред
4) рдпрд╣ рдЧрд╛рд░рдВрдЯреА рджреА рдЬрд╛рддреА рд╣реИ рдХрд┐ рдбрд┐рдХреЛрдбрд░ OutOfMemoryError рдХреЗ рдмрд┐рдирд╛ рдердВрдмрдиреЗрд▓ рд▓реМрдЯрд╛рдПрдЧрд╛
рдиреЛрдЯ: рдореБрдЭреЗ рдЫрд╡рд┐ рдХрд╛ рдЖрдХрд╛рд░ рд╕реНрдХреНрд░реАрди рдХреЗ рдЖрдХрд╛рд░ рд╕реЗ рдмрдбрд╝рд╛ рдмрдирд╛рдиреЗ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдореБрдЭреЗ ARGB_888 рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдмрд┐рдЯрдореИрдк рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХрд╛ рдХреЛрдИ рдХрд╛рд░рдг рдирд╣реАрдВ рджрд┐рдЦрддрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдХрдИ рдЙрдкрдХрд░рдгреЛрдВ рдореЗрдВ 16 рдмрд┐рдЯ рд╕реНрдХреНрд░реАрди рд╣реИрдВред рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХ рд░рдВрдЧреАрди рд╕реНрдХреНрд░реАрди рдкрд░ рднреА, рдореЗрдореЛрд░реА рдХреА рдЦрдкрдд рдореЗрдВ рджреЛ рдЧреБрдирд╛ рдХрдореА рдХрд╛ рд▓рд╛рдн рдЫрд╡рд┐ рдЧреБрдгрд╡рддреНрддрд╛ (IMHO) рдореЗрдВ рдорд╛рдореВрд▓реА рдХрдореА рд╕реЗ рдЕрдзрд┐рдХ рд╣реИред
рдЖрдЧреЗ рдХреНрдпрд╛ рд╣реИ?
рдпрджрд┐ рдЖрдкрдХреЛ рдЪреМрдбрд╝рд╛рдИ рдФрд░ рдКрдВрдЪрд╛рдИ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдЯреАрдХ рдорд┐рд▓рд╛рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рддреЛ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдмрд┐рдЯрдореИрдк рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ, рдЕрдиреНрдпрдерд╛ рдЫрд╡рд┐ рдХреЛ рдЖрдХрд╛рд░ рдФрд░ / рдпрд╛ рдХреНрд░реЙрдк рдХрд░реЗрдВред рдЗрди рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рддреБрдЪреНрдЫ рд╣реИ, рдкреЛрд╕реНрдЯ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕реНрд░реЛрдд рдХреЛрдбред
EXIF рдЕрднрд┐рд╡рд┐рдиреНрдпрд╛рд╕ рдпрд╛ рд╕рд╣реА рдЙрд▓реНрдЯреЗ рдЪрд┐рддреНрд░ред
рдпрд╣ рд╕рдорд╛рдзрд╛рди рдХреЗрд╡рд▓ jpeg рдкреНрд░рд╛рд░реВрдк рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред
рдЗрд╕ рдмрд╛рдд рдХреА рдХреЛрдИ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЫрд╡рд┐ рдореЗрдВ рд╡рд╕реНрддреБрдУрдВ рдХреЛ рд╣рдореЗрд╢рд╛ рдШреБрдорд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рд╣рдо рдЙрдиреНрд╣реЗрдВ рджреЗрдЦрддреЗ рд╣реИрдВред рдпрд╣ рд╕реНрдорд╛рд░реНрдЯрдлреЛрди рдХреЗ рдХреИрдорд░реЗ рдХреЛ рдХрд┐рд╕реА рднреА рдХреЛрдг рдкрд░ рдШреБрдорд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ - рдФрд░ рдпрд╣рд╛рдВ рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдРрд╕реА рдЫрд╡рд┐ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк рдХрд╣реАрдВ рдФрд░ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдореИрдВ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдордХрд╛рди рдФрд░ рд▓реЛрдЧ рдЬрдореАрди рдкрд░ рдЦрдбрд╝реЗ рд╣реЛрдВ, рдФрд░ рдЖрдХрд╛рд╢ рдореЗрдВ рдЙрдбрд╝рдиреЗ рд╡рд╛рд▓реЗ рдкрдХреНрд╖реАред EXIF рдмрдЪрд╛рд╡ рдореЗрдВ рдЖрддрд╛ рд╣реИ - рдПрдХ рдкреНрд░рд╛рд░реВрдк рдЬреЛ рдЖрдкрдХреЛ рдЫрд╡рд┐рдпреЛрдВ рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА рдЬреЛрдбрд╝рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рд╣рдо рдХреЗрд╡рд▓ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ - рдЕрднрд┐рд╡рд┐рдиреНрдпрд╛рд╕ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рдЬрд┐рд╕реЗ рд╕реНрдорд╛рд░реНрдЯрдлреЛрди рдХрд╛ рд╕реНрдорд╛рд░реНрдЯрдлреЛрди рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдореЗрдВ рдЬреЛрдбрд╝рддрд╛ рд╣реИ (рдореИрдВ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рд╕рднреА рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рдХреИрдорд░реЗ рдРрд╕рд╛ рдХрд░рддреЗ рд╣реИрдВ)ред рд▓реЗрдХрд┐рди рдЕрдкрдиреЗ рдХрдЪреНрдЪреЗ рд░реВрдк рдореЗрдВ, рдпрд╣ рд░реЛрдЯреЗрд╢рди рдХреА рдбрд┐рдЧреНрд░реА рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ 1-8 рдХрд╛ рдбрд┐рдЬрд┐рдЯрд▓ рдореВрд▓реНрдп рд░рдЦрддрд╛ рд╣реИред рдЗрди рдореВрд▓реНрдпреЛрдВ рдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ,
рдпрд╣рд╛рдВ рд╡рд░реНрдгрд┐рдд
рд╣реИ ред рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ, рдореБрдЭреЗ рдпрд╛рдж рдирд╣реАрдВ рд╣реИ рдХрд┐ рдЙрдирдХрд╛ рдХреНрдпрд╛ рдорддрд▓рдм рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдкреЛрд╕реНрдЯ рдХреЗ рдЕрдВрдд рдореЗрдВ рдПрдХ рддреИрдпрд╛рд░ рдХрд┐рдП рдЧрдП рдлрд╝рдВрдХреНрд╢рди рдХреЛ рд▓реЗрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВ, рдЬреЛ рдЗрди рдореВрд▓реНрдпреЛрдВ рдХреЛ рдбрд┐рдЧреНрд░реА рдореЗрдВ рдЕрдиреБрд╡рд╛рдж рдХрд░рддрд╛ рд╣реИ: getOrientation (рд╕рдВрджрд░реНрдн рд╕рдВрджрд░реНрдн, рдЙрд░реА рдЙрд░реА)ред рдлрд╝рдВрдХреНрд╢рди 90, 180, 270, 0 рдпрд╛ -1 (рдПрдХ рддреНрд░реБрдЯрд┐ рд╕реНрдерд┐рддрд┐ рдЬрдм рдПрдХ рдХрд╛рд░рдг рдпрд╛ рдХрд┐рд╕реА рдЕрдиреНрдп рдХреЗ рд▓рд┐рдП рд░реЛрдЯреЗрд╢рди рдХреЛрдг рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рдирд╣реАрдВ рдерд╛) рдХреЗ рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИред рддрджрдиреБрд╕рд╛рд░, рд░реЛрдЯреЗрд╢рди рдХреЛ рдПрдХ рдорд╛рди> 0 рдХреЗ рд╕рд╛рде рдЖрд╡рд╢реНрдпрдХ рд╣реИред
рдЫрд╡рд┐ рдХреЛ рд╕рд╣реА рдХреЛрдг рдкрд░ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЫрд╡рд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдХреЛ рдкреВрд░рдХ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
рдмрдЬрд╛рдп:
int origWidth = o.outWidth;
рд▓рд┐рдЦреЗрдВ:
int origWidth = 0;
рдФрд░ рдЕрдВрдд рдореЗрдВ рд╣рдо рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ:
if (orientation > 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation); Bitmap decodedBitmap = bitmap; bitmap = Bitmap.createBitmap(decodedBitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
рдЕрджреНрдпрддрди резрдЫрд╡рд┐ рдХрд╛ рдЕрдиреБрдХреВрд▓рди рдХрд░реЗрдВ
рдЪреМрдбрд╝рд╛рдИ рдФрд░ рдКрдВрдЪрд╛рдИ
ImageManager рд╡рд░реНрдЧ рджреЛ enums ScaleMode рдФрд░ ResizeMode рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рджреЛ рдореВрд▓реНрдп рд╣реИрдВ, EQUAL_OR_GREATER рдФрд░ EQUAL_OR_LOWERред
рд╕реНрдХреЗрд▓рдореЛрдб рдХреЗ рд▓рд┐рдП:
- EQUAL_OR_GREATER рдХрд╛ рдЕрд░реНрде рд╣реЛрдЧрд╛ рдХрд┐ рдбрд┐рдХреЛрдбрд░ рджреНрд╡рд╛рд░рд╛ рдХрдо рдХрд┐рдпрд╛ рдЧрдпрд╛ рдЪрд┐рддреНрд░ рд╣рдореЗрд╢рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЪреМрдбрд╝рд╛рдИ x рдКрдБрдЪрд╛рдИ рдХреЗ рдмрд░рд╛рдмрд░ рдпрд╛ рдереЛрдбрд╝рд╛ рдмрдбрд╝рд╛ рд╣реЛрдЧрд╛
- EQUAL_OR_LOWER рдХрд╛ рдЕрд░реНрде рд╣реЛрдЧрд╛ рдХрд┐ рдбрд┐рдХреЛрдбрд░ рджреНрд╡рд╛рд░рд╛ рдХрдо рдХреА рдЧрдИ рддрд╕реНрд╡реАрд░ рд╣рдореЗрд╢рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЪреМрдбрд╝рд╛рдИ x рдКрдБрдЪрд╛рдИ рд╕реЗ рдереЛрдбрд╝реА рдХрдо рд╣реЛрдЧреА
ResizeMode рдХреЗ рд▓рд┐рдП:
- EQUAL_OR_GREATER рдХрд╛ рдЕрд░реНрде рд╣реЛрдЧрд╛ рдХрд┐ рдЫрд╡рд┐ рдХреЗ рджреЛрдиреЛрдВ рдкрдХреНрд╖ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЪреМрдбрд╝рд╛рдИ x рдКрдВрдЪрд╛рдИ рдХреЗ рдмрд░рд╛рдмрд░ рдпрд╛ рдЙрд╕рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛрдВрдЧреЗ
- EQUAL_OR_LOWER рдХрд╛ рдЕрд░реНрде рд╣реЛрдЧрд╛ рдХрд┐ рдЪрд┐рддреНрд░ рдЪреМрдбрд╝рд╛рдИ x рдКрдБрдЪрд╛рдИ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЖрдпрдд рдореЗрдВ рдлрд┐рдЯ рд╣реЛрдЧрд╛ (рд╕рднреА рдкрдХреНрд╖ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдЪреМрдбрд╝рд╛рдИ x рдКрдБрдЪрд╛рдИ рдХреЗ рдмрд░рд╛рдмрд░ рдпрд╛ рдХрдо рд╣реИрдВ)
рдпрджрд┐ рдЫрд╡рд┐ рдХрд╛ рдЖрдХрд╛рд░, рдореЗрдореЛрд░реА рдХреА рдЦрдкрдд, рдПрд╕рдбреА рдХрд╛рд░реНрдб рдкрд░ рд╕реНрдерд╛рди, 2g / 3G рдХреА рдбрд╛рдЙрдирд▓реЛрдб рдЧрддрд┐ рджреНрд╡рд┐рддреАрдпрдХ рдирд╣реАрдВ рд╣реИ, рддреЛ EQUAL_OR_LOWER рдореЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рд╕рд┐рдлрд╛рд░рд┐рд╢ рдХреА рдЬрд╛рддреА рд╣реИ, рдЬреЛ рдЫрд╡рд┐ рдЧреБрдгрд╡рддреНрддрд╛ рдореЗрдВ рдорд╛рдореВрд▓реА рдХрдореА рдХреЗ рдХрд╛рд░рдг рдЗрди рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдХрдо рдХрд░ рджреЗрдЧрд╛ред рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ, рдореИрдВ рдЬрд▓реНрджреА рд╕реЗ рдЗрд╕ рд╕рдордЭреМрддреЗ рдкрд░ рдЖ рдЧрдпрд╛, рдХреНрдпреЛрдВрдХрд┐ 2 рдЬреА рдкрд░ рдЫрд╡рд┐рдпрд╛рдВ рднреЗрдЬрддреЗ / рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╕рдордп, рдЧрддрд┐ рдЖрдорддреМрд░ рдкрд░ рд╡рд╛рдВрдЫрд┐рдд рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдХреБрдЫ рдЫреЛрдбрд╝ рджреЗрддреА рд╣реИ (рд╡рд┐рд╢реЗрд╖рдХрд░ рдЕрд╕реНрдерд┐рд░ рд╕рдВрдХреЗрдд рдХреА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ, рдЬреЛ рди рдХреЗрд╡рд▓ рд╕реБрд░рдВрдЧреЛрдВ рдФрд░ рдореЗрдЯреНрд░реЛ рдореЗрдВ рд╣реЛрддреА рд╣реИ)ред
рдЬреЗрдкреАрдИрдЬреА рд╕рдВрдкреАрдбрд╝рди рджрд░
рд▓реЗрдХрд┐рди рдЕрдЧрд░ ScaleMode рдФрд░ ResizeMode рдЖрдкрдХреЛ рдЪреМрдбрд╝рд╛рдИ рдФрд░ рдКрдВрдЪрд╛рдИ рдореЗрдВ "рдмрдЪрд╛рдиреЗ" рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рддреЛ рдЫрд╡рд┐ рдХрд╛ рдЖрдХрд╛рд░ рдХрдо рдХрд░рдиреЗ рдХрд╛ рдПрдХ рдФрд░ рддрд░реАрдХрд╛ рд╣реИ: jpeg рд╕рдВрдкреАрдбрд╝рди рджрд░ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, ImageManager рд╡рд░реНрдЧ рдореЗрдВ, рдореИрдВрдиреЗ рдПрдХ рд╡рд┐рдзрд┐ рдФрд░ рдЗрд╕рдХрд╛ рдЕрдзрд┐рднрд╛рд░ рд▓рд┐рдЦрд╛ рд╣реИ:
byte[] getRawFromFile(String path, int compressRate) byte[] getRawFromFile(String path)
рд╣рд╛рд░реНрдбрдХреЛрдб рдХреЗ рд╕рд╛рде рд╡рд┐рдзрд┐ рдХреЛ рдУрд╡рд░рд▓реЛрдб рдХрд░рдиреЗ рдореЗрдВ, рдкреИрд░рд╛рдореАрдЯрд░ рдЕрдиреБрднрд╡рдЬрдиреНрдп рд░реВрдк рд╕реЗ рдЕрдиреБрдорд╛рдирд┐рдд рдкреИрд░рд╛рдореАрдЯрд░ 75 рдореЗрдВ рд╕рдВрдЪрд╛рд▓рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЗрд╕ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдореИрдВ рдХрд░рддрд╛ рд╣реВрдВ, рд╕реНрдХреИрд▓реНрдореЛрдб рдФрд░ ResizeMode рдХреЗ рд╕рд╛рде рдорд┐рд▓рдХрд░, рдмрд╛рдЗрдЯ рд╕рд░рдгреА рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдиреБрдХреВрд▓рд┐рдд jpeg рдЫрд╡рд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЬреЛ рдЗрд╕реЗ рд╕рд░реНрд╡рд░ рдкрд░ рдкреЛрд╕реНрдЯ рдореЗрдВ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╣реИред
рдЕрдВрддрднрд╛рд╖рдг
рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдореИрдиреБрдЕрд▓ рди рдХреЗрд╡рд▓ рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИ, рдмрд▓реНрдХрд┐ рд╕рдордЭ рднреА рджреЗрддрд╛ рд╣реИред рдмрд┐рдирд╛ рд╕реЛрдЪреЗ-рд╕рдордЭреЗ рдХреЙрдкреА-рдкреЗрд╕реНрдЯ рд╕реЗ рд╢реЙрд░реНрдЯ рдЯрд░реНрдо рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд▓рдВрдмреА рдЕрд╡рдзрд┐ рдореЗрдВ рдпрд╣ рдФрд░ рднреА рдмрдбрд╝реА рдЧрд▓рддрд┐рдпрд╛рдВ рд╣реЛ рд╕рдХрддреА рд╣реИред
ImageManager рд╡рд░реНрдЧ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ public final class ImageManager { private Context _ctx; private int _boxWidth; private int _boxHeight; private ResizeMode _resizeMode; private ScaleMode _scaleMode; private Config _rgbMode; private boolean _isScale; private boolean _isResize; private boolean _isCrop; private boolean _isRecycleSrcBitmap; private boolean _useOrientation; public ImageManager(Context ctx, int boxWidth, int boxHeight) { this(ctx); _boxWidth = boxWidth; _boxHeight = boxHeight; } public ImageManager(Context ctx) { _ctx = ctx; _isScale = false; _isResize = false; _isCrop = false; _isRecycleSrcBitmap = true; _useOrientation = false; } public ImageManager setResizeMode(ResizeMode mode) { _resizeMode = mode; return this; } public ImageManager setScaleMode(ScaleMode mode) { _scaleMode = mode; return this; } public ImageManager setRgbMode(Config mode) { _rgbMode = mode; return this; } public ImageManager setIsScale(boolean isScale) { _isScale = isScale; return this; } public ImageManager setIsResize(boolean isResize) { _isResize = isResize; return this; } public ImageManager setIsCrop(boolean isCrop) { _isCrop = isCrop; return this; } public ImageManager setUseOrientation(boolean value) { _useOrientation = value; return this; } public ImageManager setIsRecycleSrcBitmap(boolean value) { _isRecycleSrcBitmap = value; return this; } public Bitmap getFromFile(String path) { Uri uri = Uri.parse(path); int orientation = -1; if (_useOrientation) { orientation = getOrientation(_ctx, uri); } Bitmap bitmap = scale(new StreamFromFile(_ctx, path), orientation); return getFromBitmap(bitmap); } public Bitmap getFromBitmap(Bitmap bitmap) { if (bitmap == null) return null; if (_isResize) bitmap = resize(bitmap); if (_isCrop) bitmap = crop(bitmap); return bitmap; } public byte[] getRawFromFile(String path) { return getRawFromFile(path, 75); } public byte[] getRawFromFile(String path, int compressRate) { Bitmap scaledBitmap = getFromFile(path); if (scaledBitmap == null) return null; ByteArrayOutputStream output = new ByteArrayOutputStream(); scaledBitmap.compress(CompressFormat.JPEG, compressRate, output); recycleBitmap(scaledBitmap); byte[] rawImage = output.toByteArray(); if (rawImage == null) { return null; } return rawImage; } public Bitmap getFromByteArray(byte[] rawImage) { Bitmap bitmap = scale(new StreamFromByteArray(rawImage), -1); return getFromBitmap(bitmap); } @SuppressLint("NewApi") private Bitmap scale(IStreamGetter streamGetter, int orientation) { try { InputStream in = streamGetter.Get(); if (in == null) return null; Bitmap bitmap = null; Config rgbMode = _rgbMode != null ? _rgbMode : Config.RGB_565; if (!_isScale) { BitmapFactory.Options o = new BitmapFactory.Options(); o.inPreferredConfig = rgbMode; if (android.os.Build.VERSION.SDK_INT >= 11) { o.inMutable = true; } bitmap = BitmapFactory.decodeStream(in, null, o); in.close(); return bitmap; } if (_boxWidth == 0 || _boxHeight == 0) { if (in != null) in.close(); return null; } ScaleMode scaleMode = _scaleMode != null ? _scaleMode : ScaleMode.EQUAL_OR_GREATER; int bytesPerPixel = rgbMode == Config.ARGB_8888 ? 4 : 2; int maxSize = 480 * 800 * bytesPerPixel; int desiredSize = _boxWidth * _boxHeight * bytesPerPixel; if (desiredSize < maxSize) maxSize = desiredSize; BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(in, null, o); in.close(); int scale = 1; int origWidth; int origHeight; if (orientation == 90 || orientation == 270) { origWidth = o.outHeight; origHeight = o.outWidth; } else { origWidth = o.outWidth; origHeight = o.outHeight; } while ((origWidth * origHeight * bytesPerPixel) * (1 / Math.pow(scale, 2)) > maxSize) { scale++; } if (scaleMode == ScaleMode.EQUAL_OR_LOWER) { scale++; } o = new BitmapFactory.Options(); o.inSampleSize = scale; o.inPreferredConfig = rgbMode; in = streamGetter.Get(); if (in == null) return null; bitmap = BitmapFactory.decodeStream(in, null, o); in.close(); if (orientation > 0) { Matrix matrix = new Matrix(); matrix.postRotate(orientation); Bitmap decodedBitmap = bitmap; bitmap = Bitmap.createBitmap(decodedBitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); if (decodedBitmap != null && !decodedBitmap.equals(bitmap)) { recycleBitmap(decodedBitmap); } } return bitmap; } catch (IOException e) { return null; } } private Bitmap resize(Bitmap sourceBitmap) { if (sourceBitmap == null) return null; if (_resizeMode == null) _resizeMode = ResizeMode.EQUAL_OR_GREATER; float srcRatio; float boxRatio; int srcWidth = 0; int srcHeight = 0; int resizedWidth = 0; int resizedHeight = 0; srcWidth = sourceBitmap.getWidth(); srcHeight = sourceBitmap.getHeight(); if (_resizeMode == ResizeMode.EQUAL_OR_GREATER && (srcWidth <= _boxWidth || srcHeight <= _boxHeight) || _resizeMode == ResizeMode.EQUAL_OR_LOWER && srcWidth <= _boxWidth && srcHeight <= _boxHeight) { return sourceBitmap; } srcRatio = (float)srcWidth / (float)srcHeight; boxRatio = (float)_boxWidth / (float)_boxHeight; if (srcRatio > boxRatio && _resizeMode == ResizeMode.EQUAL_OR_GREATER || srcRatio < boxRatio && _resizeMode == ResizeMode.EQUAL_OR_LOWER) { resizedHeight = _boxHeight; resizedWidth = (int)((float)resizedHeight * srcRatio); } else { resizedWidth = _boxWidth; resizedHeight = (int)((float)resizedWidth / srcRatio); } Bitmap resizedBitmap = Bitmap.createScaledBitmap(sourceBitmap, resizedWidth, resizedHeight, true); if (_isRecycleSrcBitmap && !sourceBitmap.equals(resizedBitmap)) { recycleBitmap(sourceBitmap); } return resizedBitmap; } private Bitmap crop(Bitmap sourceBitmap) { if (sourceBitmap == null) return null; int srcWidth = sourceBitmap.getWidth(); int srcHeight = sourceBitmap.getHeight(); int croppedX = 0; int croppedY = 0; croppedX = (srcWidth > _boxWidth) ? (int)((srcWidth - _boxWidth) / 2) : 0; croppedY = (srcHeight > _boxHeight) ? (int)((srcHeight - _boxHeight) / 2) : 0; if (croppedX == 0 && croppedY == 0) return sourceBitmap; Bitmap croppedBitmap = null; try { croppedBitmap = Bitmap.createBitmap(sourceBitmap, croppedX, croppedY, _boxWidth, _boxHeight); } catch(Exception e) { } if (_isRecycleSrcBitmap && !sourceBitmap.equals(croppedBitmap)) { recycleBitmap(sourceBitmap); } return croppedBitmap; } public static void recycleBitmap(Bitmap bitmap) { if (bitmap == null || bitmap.isRecycled()) return; bitmap.recycle(); System.gc(); } private static interface IStreamGetter { public InputStream Get(); } private static class StreamFromFile implements IStreamGetter { private String _path; private Context _ctx; public StreamFromFile(Context ctx, String path) { _path = path; _ctx = ctx; } @SuppressWarnings("resource") public InputStream Get() { try { Uri uri = Uri.parse(_path); return "content".equals(uri.getScheme()) ? _ctx.getContentResolver().openInputStream(uri) : new FileInputStream(_path); } catch (FileNotFoundException e) { return null; } } } private static class StreamFromByteArray implements IStreamGetter { private byte[] _rawImage; public StreamFromByteArray(byte[] rawImage) { _rawImage = rawImage; } public InputStream Get() { if (_rawImage == null) return null; return new ByteArrayInputStream(_rawImage); } } private static int getOrientation(Context context, Uri uri) { if ("content".equals(uri.getScheme())) { Cursor cursor = context.getContentResolver().query(uri, new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null); if (cursor == null || cursor.getCount() != 1) { return -1; } cursor.moveToFirst(); int orientation = cursor.getInt(0); cursor.close(); return orientation; } else { try { ExifInterface exif = new ExifInterface(uri.getPath()); int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, -1); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_270: return 270; case ExifInterface.ORIENTATION_ROTATE_180: return 180; case ExifInterface.ORIENTATION_ROTATE_90: return 90; case ExifInterface.ORIENTATION_NORMAL: return 0; default: return -1; } } catch (IOException e) { return -1; } } } }