Skip to content

Commit

Permalink
1.0.2
Browse files Browse the repository at this point in the history
  • Loading branch information
agentphantom committed Aug 7, 2016
1 parent 8eb1a2a commit a61fe8b
Show file tree
Hide file tree
Showing 5 changed files with 237 additions and 24 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Icon Generator 1.0.0
# Icon Generator 1.0.2

Icon Generator is a desktop application developed with Apache Flex and Adobe AIR that helps developers in the task of automating the generation of graphic assets in several sizes.

Expand All @@ -10,7 +10,7 @@ Some of the key features are:
- Generation of iOS launch screens for iPhones and iPads in Portrait and landscape modes.
- Free and open source!

This application is based on the [Application Icons](http://help.adobe.com/en_US/air/build/WS901d38e593cd1bac1e63e3d129907d2886-8000.html) article from AIR's site.
This application is based on the [Application Icons](http://help.adobe.com/en_US/air/build/WS901d38e593cd1bac1e63e3d129907d2886-8000.html) article from Adobe AIR's site.

To compile this application you will require the [PNGEncoder2 library](https://github.com/cameron314/PNGEncoder2) and recent versions of Apache Flex and Adobe AIR SDKs.

Expand All @@ -20,7 +20,7 @@ To compile this application you will require the [PNGEncoder2 library](https://g

You can test this app by downloading it directly from GitHub. You only require to have the AIR runtime installed on your Windows or OSX machine.

[![Download](http://i.imgur.com/333OC0X.png)](https://github.com/PhantomAppDevelopment/icon-generator/releases/download/1.0.0/IconGenerator.air)
[![Download](http://i.imgur.com/333OC0X.png)](https://github.com/PhantomAppDevelopment/icon-generator/releases/download/1.0.2/IconGenerator.air)

## Donations

Expand Down
126 changes: 126 additions & 0 deletions src/utils/Bicubic.as
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package utils
{
import flash.display.BitmapData;
import flash.filters.BitmapFilterQuality;
import flash.filters.BlurFilter;
import flash.geom.Point;

public class Bicubic
{
/**
* Resize an Image with bicubic interpolation
* @param width the new desired width
* @param height the new desired height
* @param bitmapData the original sized BitmapData
* @return
*/
public static function interpolateBicubic(bitmapData:BitmapData, width:int, height:int):BitmapData
{
// same size no need to resize
if( width == bitmapData.width && height == bitmapData.height )
{
return bitmapData.clone();
}

var interpolated :BitmapData = new BitmapData( width, height, true, 0x00000000 );
var original_copy :BitmapData = bitmapData.clone();

var xFactor:Number = bitmapData.width / interpolated.width;
var yFactor:Number = bitmapData.height / interpolated.height;

if (xFactor > 1 || yFactor > 1)
original_copy.applyFilter(original_copy, original_copy.rect, new Point(0, 0), new BlurFilter(1.4*(xFactor/2),1.4*(yFactor/2),BitmapFilterQuality.HIGH));

var step:int = 0;
while ( step < interpolated.width )
{
for (var y:int = 0; y < interpolated.height; y++){
interpolated.setPixel32(step, y, getPixelBicubic32(step * xFactor, y * yFactor, original_copy));
}
step++;
}

return interpolated;
}

private static function getPixelBicubic32( x:Number, y:Number, bitmapData:BitmapData ):Number
{
var i:int = int(x);
var j:int = int(y);

if (((i - 1) < 0) || ((j - 1) < 0))
return bitmapData.getPixel32(i, j);
else if (((i + 1) >= bitmapData.width) || ((i + 2) >= bitmapData.width) ||
((j + 1) >= bitmapData.height) || ((j + 2) >= bitmapData.height))
return bitmapData.getPixel32(i, j);

var dx :Number = x - i;
var dy :Number = y - j;
var asum:Number = 0;
var rsum:Number = 0;
var gsum:Number = 0;
var bsum:Number = 0;

var Rmdx:Array = new Array(4);
var Rdyn:Array = new Array(4);
for( var m:int = -1; m <= 2; ++m )
Rmdx[m + 1] = A(m - dx);
for( var n:int = -1; n <= 2; ++n )
Rdyn[n + 1] = A(dy - n);

for( m = -1; m <= 2; ++m )
{
for (n = -1; n <= 2; ++n)
{
var rgb :int = bitmapData.getPixel32(i + m, j + n);
var a :int = (rgb >> 24) & 0x0FF;
var r :int = (rgb >> 16) & 0x0FF;
var g :int = (rgb >> 8) & 0x0FF;
var b :int = (rgb >> 0) & 0x0FF;

var Rres:Number = Rmdx[m + 1] * Rdyn[n + 1];
asum += a * Rres;
rsum += r * Rres;
gsum += g * Rres;
bsum += b * Rres;
}
}

var alpha:int = (int)(asum + 0.5);
if(alpha < 0)
alpha = 0;
else if(alpha > 255)
alpha = 255;

var red:int = (int)(rsum + 0.5);
if(red < 0)
red = 0;
else if(red > 255)
red = 255;

var green:int = (int)(gsum + 0.5);
if(green < 0)
green = 0;
else if(green > 255)
green = 255;

var blue:int = (int)(bsum + 0.5);
if(blue < 0)
blue = 0;
else if(blue > 255)
blue = 255;

return (alpha << 24) | (red << 16) | (green << 8) | (blue << 0);
}

private static function A( x:Number ):Number
{
var p0:Number = ((x + 2) > 0) ? (x + 2) : 0;
var p1:Number = ((x + 1) > 0) ? (x + 1) : 0;
var p2:Number = (x > 0) ? x : 0;
var p3:Number = ((x - 1) > 0) ? (x - 1) : 0;

return (1 / 6) * (p0 * p0 * p0 - 4 * (p1 * p1 * p1) + 6 * (p2 * p2 * p2) - 4 * (p3 * p3 * p3));
}
}
}
50 changes: 46 additions & 4 deletions src/views/IconView.mxml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
import spark.components.CheckBox;
import spark.events.IndexChangeEvent;

import utils.Bicubic;

[Bindable] private var AllArray:Array;
[Bindable] private var AndroidArray:Array;
[Bindable] private var iOSArray:Array;
Expand All @@ -20,7 +22,9 @@
[Bindable] private var preset2:Array;
[Bindable] private var preset3:Array;

private var bicubic:Boolean;
private var fileRef:FileReference;
private var settings:Object;

protected function init(event:FlexEvent):void
{
Expand Down Expand Up @@ -63,32 +67,65 @@
{
currentState = "ExportState";
loadCustomPresets();

settings = new Object();
loadSettings();

generateCheckboxes();
}

private function loadCustomPresets():void
{
{
var file:File = File.applicationStorageDirectory.resolvePath("iconpresets.data");

if(file.exists)
{
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);

if(fileStream.bytesAvailable == 0){
if(file.size <= 1){
fileStream.close();
} else {
var presets:Object = fileStream.readObject();

preset1 = String(presets.preset1).split(",");
preset2 = String(presets.preset2).split(",");
preset3 = String(presets.preset3).split(",");
trace(preset3);
fileStream.close();
}
}
}

private function loadSettings():void
{
var file:File = File.applicationStorageDirectory.resolvePath("settings.data");

if(file.exists)
{
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);

if(file.size <= 1){
fileStream.close();
} else {
settings = fileStream.readObject();

if(settings.hasOwnProperty("bicubic")){
bicubic = settings.bicubic.valueOf();
} else {
bicubic = false;
}

fileStream.close();
}
} else {

//Settings file doesn't exists, so we fallback to the defaults.

bicubic = false;
}
}

protected function generateCheckboxes():void
{
checkBoxGroup.removeAllElements();
Expand Down Expand Up @@ -125,7 +162,12 @@

var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeBytes(PNGEncoder2.encode(scaleIcon(iconLarge.bitmapData, Number(tempCheckBox.name), Number(tempCheckBox.name))));

if(bicubic == true){
fileStream.writeBytes(PNGEncoder2.encode(Bicubic.interpolateBicubic(iconLarge.bitmapData, Number(tempCheckBox.name), Number(tempCheckBox.name))));
} else {
fileStream.writeBytes(PNGEncoder2.encode(scaleIcon(iconLarge.bitmapData, Number(tempCheckBox.name), Number(tempCheckBox.name))));
}
fileStream.close();
}
}
Expand Down
15 changes: 4 additions & 11 deletions src/views/ImagesView.mxml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
<fx:Script>
<![CDATA[
import mx.controls.Alert;

import mx.events.FlexEvent;

[Bindable] private var AllArray:Array;
[Bindable] private var iPhoneAllArray:Array;
[Bindable] private var iPhonePortraitArray:Array;
Expand Down Expand Up @@ -55,12 +54,7 @@
);

iPhoneLandscapeArray = new Array(
{name:"IPad 1,2 Portrait", file:"Default-Portrait~ipad.png", w:768, h:1024},
{name:"iPad 3, Air Portrait", file:"Old-Default-Portrait@2x~ipad.png", w:1536, h:2048},
{name:"iPad Pro Portrait", file:"Default-Portrait@2x~ipad.png", w:2048, h:2732},
{name:"IPad 1,2 Landscape", file:"Default-Landscape~ipad.png", w:1024, h:768},
{name:"iPad 3, Air Landscape", file:"Old-Default-Landscape@2x~ipad.png", w:2048, h:1536},
{name:"iPad Pro Landscape", file:"Default-Landscape@2x~ipad.png", w:2732, h:2048}
{name:"iPhone 6 Plus", file:"Default-Landscape-414w-736h@3x~iphone.png", w:2208, h:1242}
);

iPadAllArray = new Array(
Expand Down Expand Up @@ -138,7 +132,7 @@
label.toolTip = sizeData.file;
return label;
}

protected function generateImage(event:MouseEvent):void
{
var folderName:Number = Math.round(Math.random()*1000000);
Expand All @@ -149,9 +143,8 @@

var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeBytes(PNGEncoder2.encode(scaleImage(imageLarge.bitmapData, optionsList.selectedItem.data[i].w, optionsList.selectedItem.data[i].h)));
fileStream.writeBytes(PNGEncoder2.encode(scaleImage(imageLarge.bitmapData, optionsList.selectedItem.data[i].w, optionsList.selectedItem.data[i].h)));
fileStream.close();

}

Alert.show("Images successfully generated at Desktop/launchscreens-" + String(folderName), "Images Generated");
Expand Down
Loading

0 comments on commit a61fe8b

Please sign in to comment.