import java.io.File;
import java.awt.Color;
import java.awt.Image;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
/**
* 实在受不了 Android Studio 里制作 9 Patch 难用的 Editor
*
* 快速生成 Android 的 Splash 的 9 Patch 图片
*
* 找最大一张图片,作为 xxxdpi,比如 1024 * 1024,生成如下尺寸的,注意图片里的上下左右空白边距必须大于 4 * 3 / 0.75 = 16 个像素
*
* xxxhdpi 1024 4.00x
*
* xxhdpi 768 3.00x
*
* xhdpi 512 2.00x
*
* hdpi 384 1.50x
*
* mdpi 256 1.00x
*
* ldpi 192 0.75x
*
* @author NeedJava@126.com
*
* @since 2025.07.12
*/
public final class Create9Patch
{
private static final Item[] ITEMS = new Item[]
{
new Item( "drawable-xxxhdpi", 4.00F ), //1024 = * 4.00F / 4
new Item( "drawable-xxhdpi", 3.00F ), // 768 = * 3.00F / 4
new Item( "drawable-xhdpi", 2.00F ), // 512 = * 2.00F / 4
new Item( "drawable-hdpi", 1.50F ), // 384 = * 1.50F / 4
new Item( "drawable-mdpi", 1.00F ), // 256 = * 1.00F / 4
new Item( "drawable-ldpi", 0.75F ), // 192 = * 0.75F / 4
};
public static void main( final String[] args ) throws Exception
{
final java.io.BufferedReader reader = new java.io.BufferedReader( new java.io.InputStreamReader( System.in ) );
while( true )
{
System.err.println( "\r\nPlease input image path and press Enter:" );
final String source = reader.readLine().trim();
final File sourceFile = new File( source.startsWith( "\"" ) && source.endsWith( "\"" ) ? source.substring( 1, source.length() - 1 ) : source );
if( sourceFile.isFile() == false ){ System.err.println( "Image not exists! " + sourceFile ); continue; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////
System.err.println( "\r\nPlease input 9 patch file name and press Enter:" );
final String outputName = reader.readLine().trim();
////////////////////////////////////////////////////////////////////////////////////////////////////////////
create( sourceFile, outputName );
System.err.println( "\r\nDONE" );
}
}
public static void create( final File oldFile, final String outputName ) throws Exception
{
final File outputFolder = new File( oldFile.getParent(), "output"/*HARD_CODE*/ );
final String oldName = isTrimEmpty( outputName ) ? "image_splash.9.png"/*HARD_CODE*/ : outputName + ".9.png"/*HARD_CODE*/;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
final BufferedImage oldImage = ImageIO.read( oldFile );
final int oldWidth = oldImage.getWidth();
final int oldHeight = oldImage.getHeight();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Item item = null; File folder = null; int newWidth = 0, newHeight = 0;
for( int i = 0; i < ITEMS.length; i ++ )
{
if( ( item = ITEMS[i] ) == null || isTrimEmpty( item.mFolder ) ){ continue; }
folder = new File( outputFolder, item.mFolder ); folder.mkdirs();
newWidth = (int) ( oldWidth * item.mTimes / 4/*HARD_CODE*/ );
newHeight = (int) ( oldHeight * item.mTimes / 4/*HARD_CODE*/ );
ImageIO.write( scaleImageByWidth( oldImage, newWidth, newHeight ), "png"/*HARD_CODE*/, new File( folder, oldName ) );
}
}
public static BufferedImage scaleImageByWidth( final BufferedImage oldImage, final int newWidth, final int newHeight )
{
final BufferedImage newImage = new BufferedImage( newWidth, newHeight, BufferedImage.TYPE_INT_ARGB );
final Graphics2D g2d = newImage.createGraphics();
g2d.drawImage( oldImage.getScaledInstance( newWidth, newHeight, Image.SCALE_SMOOTH ), 0, 0, null );
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
g2d.setColor( Color.BLACK );
//////////////////////////////////////////////////////////// Top
g2d.drawLine( 1, 0, 2, 0 );
g2d.drawLine( newWidth - 3, 0, newWidth - 2, 0 );
//////////////////////////////////////////////////////////// Left
g2d.drawLine( 0, 1, 0, 2 );
g2d.drawLine( 0, newHeight - 3, 0, newHeight - 2 );
//////////////////////////////////////////////////////////// Right
g2d.drawLine( newWidth - 1, 3, newWidth - 1, newHeight - 4 );
//////////////////////////////////////////////////////////// Bottom
g2d.drawLine( 3, newHeight - 1, newWidth - 4, newHeight - 1 );
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
g2d.dispose();
return newImage;
}
public static boolean isTrimEmpty( final String string )
{
return ( string == null ? true : string.trim().length() == 0 );
}
}
final class Item
{
public final String mFolder;
public final float mTimes;
public Item( final String folder, final float times )
{
this.mFolder = folder;
this.mTimes = times;
}
}
快速生成 Android 的 Splash 的 9 Patch 图片
于 2025-07-13 23:20:34 首次发布