Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions SignaturePad-Example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@ apply plugin: 'com.android.application'

android {
compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION

defaultConfig {
minSdkVersion 9
defaultConfig {
minSdkVersion 14
targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)
versionName project.VERSION_NAME
versionCode Integer.parseInt(project.VERSION_CODE)
Expand All @@ -18,9 +17,10 @@ android {
minifyEnabled false
}
}
buildToolsVersion '27.0.3'
}

dependencies {
compile project(":signature-pad")
compile 'com.android.support:appcompat-v7:25.3.1'
implementation project(":signature-pad")
implementation 'com.android.support:appcompat-v7:27.1.1'
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,45 +103,9 @@ public void onRequestPermissionsResult(int requestCode,
}
}

public File getAlbumStorageDir(String albumName) {
// Get the directory for the user's public pictures directory.
File file = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), albumName);
if (!file.mkdirs()) {
Log.e("SignaturePad", "Directory not created");
}
return file;
}

public void saveBitmapToJPG(Bitmap bitmap, File photo) throws IOException {
Bitmap newBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBitmap);
canvas.drawColor(Color.WHITE);
canvas.drawBitmap(bitmap, 0, 0, null);
OutputStream stream = new FileOutputStream(photo);
newBitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream);
stream.close();
}

public boolean addJpgSignatureToGallery(Bitmap signature) {
boolean result = false;
try {
File photo = new File(getAlbumStorageDir("SignaturePad"), String.format("Signature_%d.jpg", System.currentTimeMillis()));
saveBitmapToJPG(signature, photo);
scanMediaFile(photo);
result = true;
} catch (IOException e) {
e.printStackTrace();
}
return result;
}

private void scanMediaFile(File photo) {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri = Uri.fromFile(photo);
mediaScanIntent.setData(contentUri);
MainActivity.this.sendBroadcast(mediaScanIntent);
}

public boolean addSvgSignatureToGallery(String signatureSvg) {
boolean result = false;
Expand Down
7 changes: 5 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
buildscript {
repositories {
jcenter()
google()
}

dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
classpath 'com.android.tools.build:gradle:3.1.4'
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
classpath 'com.android.tools.build:gradle:3.3.0-alpha07'
}
}

Expand All @@ -16,5 +18,6 @@ allprojects {

repositories {
jcenter()
google()
}
}
6 changes: 3 additions & 3 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ POM_LICENCE_DIST=repo
POM_DEVELOPER_ID=gcacace
POM_DEVELOPER_NAME=Gianluca Cacace

ANDROID_BUILD_TARGET_SDK_VERSION=25
ANDROID_BUILD_TOOLS_VERSION=25.0.3
ANDROID_BUILD_SDK_VERSION=25
ANDROID_BUILD_TARGET_SDK_VERSION=27
ANDROID_BUILD_TOOLS_VERSION=27.0.3
ANDROID_BUILD_SDK_VERSION=27
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#Tue Aug 08 11:36:01 SGT 2017
#Thu Aug 30 09:23:55 CEST 2018
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip
5 changes: 2 additions & 3 deletions signature-pad/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,14 @@ apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'

dependencies {

}

Properties properties = new Properties()
final def bintrayPropertiesFile = project.rootProject.file('bintray.properties')
if (bintrayPropertiesFile.exists()) properties.load(bintrayPropertiesFile.newDataInputStream())

android {
compileSdkVersion Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION
compileSdkVersion 27

defaultConfig {
minSdkVersion 9
Expand All @@ -22,6 +20,7 @@ android {
dataBinding {
enabled = true
}
buildToolsVersion '27.0.3'
}

bintray {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.github.gcacace.signaturepad.utils;

import android.graphics.Bitmap;
import android.graphics.Color;

public class BitmapUtils {
public static Bitmap trim(Bitmap source) {
int firstX = 0, firstY = 0;
int lastX = source.getWidth();
int lastY = source.getHeight();
int[] pixels = new int[source.getWidth() * source.getHeight()];
source.getPixels(pixels, 0, source.getWidth(), 0, 0, source.getWidth(), source.getHeight());
loop:
for (int x = 0; x < source.getWidth(); x++) {
for (int y = 0; y < source.getHeight(); y++) {
if (pixels[x + (y * source.getWidth())] != Color.TRANSPARENT) {
firstX = x;
break loop;
}
}
}
loop:
for (int y = 0; y < source.getHeight(); y++) {
for (int x = firstX; x < source.getWidth(); x++) {
if (pixels[x + (y * source.getWidth())] != Color.TRANSPARENT) {
firstY = y;
break loop;
}
}
}
loop:
for (int x = source.getWidth() - 1; x >= firstX; x--) {
for (int y = source.getHeight() - 1; y >= firstY; y--) {
if (pixels[x + (y * source.getWidth())] != Color.TRANSPARENT) {
lastX = x;
break loop;
}
}
}
loop:
for (int y = source.getHeight() - 1; y >= firstY; y--) {
for (int x = source.getWidth() - 1; x >= firstX; x--) {
if (pixels[x + (y * source.getWidth())] != Color.TRANSPARENT) {
lastY = y;
break loop;
}
}
}
return Bitmap.createBitmap(source, firstX, firstY, lastX - firstX, lastY - firstY);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import com.github.gcacace.signaturepad.R;
import com.github.gcacace.signaturepad.utils.Bezier;
import com.github.gcacace.signaturepad.utils.BitmapUtils;
import com.github.gcacace.signaturepad.utils.ControlTimedPoints;
import com.github.gcacace.signaturepad.utils.SvgBuilder;
import com.github.gcacace.signaturepad.utils.TimedPoint;
Expand Down Expand Up @@ -60,9 +61,9 @@ public class SignaturePad extends View {

//Default attribute values
private final int DEFAULT_ATTR_PEN_MIN_WIDTH_PX = 3;
private final int DEFAULT_ATTR_PEN_MAX_WIDTH_PX = 7;
private final int DEFAULT_ATTR_PEN_MAX_WIDTH_PX = 10;
private final int DEFAULT_ATTR_PEN_COLOR = Color.BLACK;
private final float DEFAULT_ATTR_VELOCITY_FILTER_WEIGHT = 0.9f;
private final float DEFAULT_ATTR_VELOCITY_FILTER_WEIGHT = 0.3f;
private final boolean DEFAULT_ATTR_CLEAR_ON_DOUBLE_CLICK = false;

private Paint mPaint = new Paint();
Expand Down Expand Up @@ -101,6 +102,7 @@ public SignaturePad(Context context, AttributeSet attrs) {

}

/*
@Override
protected Parcelable onSaveInstanceState() {
Bundle bundle = new Bundle();
Expand All @@ -110,7 +112,7 @@ protected Parcelable onSaveInstanceState() {
}
bundle.putParcelable("signatureBitmap", this.mBitmapSavedState);
return bundle;
}
}*/

@Override
protected void onRestoreInstanceState(Parcelable state) {
Expand Down Expand Up @@ -211,17 +213,17 @@ public boolean onTouchEvent(MotionEvent event) {
if (isDoubleClick()) break;
mLastTouchX = eventX;
mLastTouchY = eventY;
addPoint(getNewPoint(eventX, eventY));
addPoint(getNewPoint(eventX, eventY), event.getPressure());
if(mOnSignedListener != null) mOnSignedListener.onStartSigning();

case MotionEvent.ACTION_MOVE:
resetDirtyRect(eventX, eventY);
addPoint(getNewPoint(eventX, eventY));
addPoint(getNewPoint(eventX, eventY), event.getPressure());
break;

case MotionEvent.ACTION_UP:
resetDirtyRect(eventX, eventY);
addPoint(getNewPoint(eventX, eventY));
addPoint(getNewPoint(eventX, eventY), event.getPressure());
getParent().requestDisallowInterceptTouchEvent(true);
setIsEmpty(false);
break;
Expand Down Expand Up @@ -270,6 +272,16 @@ public Bitmap getSignatureBitmap() {
return whiteBgBitmap;
}

public Bitmap getTrimmedSignatureBitmap(boolean transparent) {
Bitmap originalBitmap = BitmapUtils.trim(getTransparentSignatureBitmap());

Bitmap whiteBgBitmap = Bitmap.createBitmap(originalBitmap.getWidth(), originalBitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(whiteBgBitmap);
canvas.drawColor(transparent ? Color.TRANSPARENT : Color.WHITE);
canvas.drawBitmap(originalBitmap, 0, 0, null);
return whiteBgBitmap;
}

public void setSignatureBitmap(final Bitmap signature) {
// View was laid out...
if (ViewCompat.isLaidOut(this)) {
Expand Down Expand Up @@ -437,7 +449,7 @@ private void recyclePoint(TimedPoint point) {
mPointsCache.add(point);
}

private void addPoint(TimedPoint newPoint) {
private void addPoint(TimedPoint newPoint, float pressure) {
mPoints.add(newPoint);

int pointsCount = mPoints.size();
Expand All @@ -464,7 +476,7 @@ private void addPoint(TimedPoint newPoint) {

// The new width is a function of the velocity. Higher velocities
// correspond to thinner strokes.
float newWidth = strokeWidth(velocity);
float newWidth = strokeWidth(velocity, pressure);

// The Bezier's width starts out as last curve's final width, and
// gradually changes to the stroke width just calculated. The new
Expand Down Expand Up @@ -553,8 +565,9 @@ private ControlTimedPoints calculateCurveControlPoints(TimedPoint s1, TimedPoint
return mControlTimedPointsCached.set(getNewPoint(m1X + tx, m1Y + ty), getNewPoint(m2X + tx, m2Y + ty));
}

private float strokeWidth(float velocity) {
return Math.max(mMaxWidth / (velocity + 1), mMinWidth);
private float strokeWidth(float velocity, float pressure) {
float velocityWidth = Math.max(mMaxWidth / (velocity + 1), mMinWidth);
return Math.max(velocityWidth*pressure,mMinWidth);
}

/**
Expand Down