1.update imageknife library adapter stage mode api 9
2.add function crop PixelMap by fingers Signed-off-by: zhoulisheng <635547767@qq.com>
This commit is contained in:
parent
76f2ff3049
commit
4db26e44b8
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"name": "@ohos/imageknife",
|
||||
"version": "1.0.2",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"pako": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "http://mirrors.tools.huawei.com/npm/pako/-/pako-1.0.11.tgz",
|
||||
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
"app": {
|
||||
"bundleName": "cn.openharmony.imageknife",
|
||||
"vendor": "openharmony",
|
||||
"version": {
|
||||
"code": 1000000,
|
||||
"name": "1.0.0"
|
||||
}
|
||||
},
|
||||
"deviceConfig": {},
|
||||
"module": {
|
||||
"package": "cn.openharmony.imageknife",
|
||||
"deviceType": [
|
||||
"phone",
|
||||
"tablet"
|
||||
],
|
||||
"distro": {
|
||||
"deliveryWithInstall": true,
|
||||
"moduleName": "imageknife",
|
||||
"moduleType": "har"
|
||||
},
|
||||
"uiSyntax": "ets"
|
||||
}
|
||||
}
|
|
@ -1,318 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {CustomMap} from './CustomMap'
|
||||
import {FileUtils} from './FileUtils'
|
||||
import {FileReader} from './FileReader'
|
||||
import {DiskCacheEntry} from './DiskCacheEntry'
|
||||
import fileio from '@ohos.fileio';
|
||||
import featureability from '@ohos.ability.featureAbility'
|
||||
import {Md5} from './Md5'
|
||||
|
||||
export class DiskLruCache {
|
||||
|
||||
// 缓存数据集合
|
||||
cacheMap: CustomMap<string, DiskCacheEntry> = new CustomMap<string, DiskCacheEntry>()
|
||||
fileUtils: FileUtils = FileUtils.getInstance()
|
||||
diskCacheFolder: string = 'ImageKnifeDiskCache'
|
||||
|
||||
// 缓存文件路劲地址
|
||||
dirPath: string= ''
|
||||
|
||||
// 缓存数据最大值
|
||||
maxSize: number = 30 * 1024 * 1024
|
||||
|
||||
// 当前缓存数据值
|
||||
size: number = 0
|
||||
|
||||
// 缓存journal文件名称
|
||||
|
||||
journal: string = 'journal'
|
||||
|
||||
// 缓存journal备份文件名称
|
||||
journalTemp: string = 'journal_temp'
|
||||
|
||||
// 缓存journal文件路径
|
||||
journalPath: string = ''
|
||||
|
||||
// 缓存journal备份文件路径
|
||||
journalPathTemp: string = ''
|
||||
|
||||
constructor(maxSize: number, direction?: string) {
|
||||
if (maxSize > 0) {
|
||||
this.maxSize = maxSize
|
||||
}
|
||||
if (!this.isNull(direction)) {
|
||||
if (direction.endsWith('/')) {
|
||||
this.dirPath = direction
|
||||
} else {
|
||||
this.dirPath = direction + '/'
|
||||
}
|
||||
} else {
|
||||
featureability.getContext()
|
||||
.getFilesDir()
|
||||
.then((data) => {
|
||||
console.log('DiskLruCache - FileDir= ' + data)
|
||||
let dirPathFolder = data + '/' + this.diskCacheFolder
|
||||
this.dirPath = dirPathFolder;
|
||||
FileUtils.getInstance()
|
||||
.createFolder(dirPathFolder)
|
||||
this.init()
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log('DiskLruCache FileDir Error Cause:' + error.message);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化缓存文件
|
||||
*/
|
||||
private init() {
|
||||
if (this.dirPath.endsWith('/')) {
|
||||
this.dirPath = this.dirPath
|
||||
} else {
|
||||
this.dirPath = this.dirPath + '/'
|
||||
}
|
||||
this.journalPath = this.dirPath + this.journal
|
||||
this.journalPathTemp = this.dirPath + this.journalTemp
|
||||
try {
|
||||
var stat = fileio.statSync(this.journalPath)
|
||||
if (stat.isFile() && stat.size > 0) {
|
||||
this.fileUtils.createFile(this.journalPathTemp)
|
||||
this.fileUtils.copyFile(this.journalPath, this.journalPathTemp)
|
||||
this.readJournal(this.journalPathTemp)
|
||||
this.resetJournalFile()
|
||||
} else {
|
||||
this.fileUtils.createFile(this.journalPath)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('DiskLruCache - init e ' + e)
|
||||
this.fileUtils.createFile(this.journalPath)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置journal文件数据
|
||||
*/
|
||||
resetJournalFile(){
|
||||
this.fileUtils.clearFile(this.journalPath)
|
||||
for(let key of this.cacheMap.keys()){
|
||||
this.fileUtils.writeData(this.journalPath, 'save ' + key + '\n')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取journal文件的缓存数据
|
||||
*/
|
||||
readJournal(path: string) {
|
||||
var fileReader = new FileReader(path)
|
||||
var line: string = ''
|
||||
while (!fileReader.isEnd()) {
|
||||
line = fileReader.readLine()
|
||||
line = line.replace('\n', '').replace('\r', '')
|
||||
this.dealwithJournal(line)
|
||||
}
|
||||
this.fileUtils.deleteFile(this.journalPathTemp)
|
||||
this.trimToSize()
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理journal文件数据
|
||||
*/
|
||||
dealwithJournal(line: string) {
|
||||
var picPath = ''
|
||||
try {
|
||||
var datas = line.split(' ')
|
||||
if (datas.length > 1) {
|
||||
if (datas[0] != 'remove') {
|
||||
picPath = this.dirPath + datas[1]
|
||||
var picstat = fileio.statSync(picPath)
|
||||
if (picstat.isFile() && picstat.size > 0) {
|
||||
this.size = this.size + picstat.size
|
||||
this.fileUtils.writeData(this.journalPath, line + '\n')
|
||||
this.putCacheMap(datas[1], picstat.size)
|
||||
}
|
||||
} else {
|
||||
if (this.cacheMap.hasKey(datas[1])) {
|
||||
var cacheEntry: DiskCacheEntry = this.cacheMap.get(datas[1])
|
||||
this.size = this.size - cacheEntry.getLength()
|
||||
this.cacheMap.remove(datas[1])
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log('DiskLruCache - dealwithJournal e = ' + e)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置disk缓存最大数据值
|
||||
*/
|
||||
setMaxSize(max: number) {
|
||||
this.maxSize = max
|
||||
this.trimToSize()
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存数据map集合
|
||||
*/
|
||||
private putCacheMap(key: string, length?: number) {
|
||||
if (this.cacheMap.hasKey(key)) {
|
||||
this.cacheMap.remove(key)
|
||||
}
|
||||
if (length > 0) {
|
||||
this.cacheMap.put(key, new DiskCacheEntry(key, length))
|
||||
} else {
|
||||
this.cacheMap.put(key, new DiskCacheEntry(key))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 存储disk缓存数据
|
||||
*/
|
||||
putCacheData(key: string, content?: ArrayBuffer, path?: string) {
|
||||
if (key == null) {
|
||||
throw new Error('key is null,checking the parameter');
|
||||
}
|
||||
var fileSize = 0
|
||||
var isvalid: boolean = false
|
||||
key = Md5.hashStr(key)
|
||||
if (content != null && content.byteLength > 0) {
|
||||
isvalid = true
|
||||
var tempPath = this.dirPath + key
|
||||
fileSize = content.byteLength
|
||||
this.fileUtils.writePic(tempPath, content)
|
||||
}
|
||||
if (!this.isNull(path) && this.fileUtils.exist(path)) {
|
||||
isvalid = true
|
||||
fileSize = this.fileUtils.getFileSize(path)
|
||||
this.fileUtils.copyFile(path, this.dirPath + key)
|
||||
}
|
||||
if (isvalid) {
|
||||
this.size = this.size + fileSize
|
||||
this.putCacheMap(key, fileSize)
|
||||
this.fileUtils.writeData(this.journalPath, 'save ' + key + '\n')
|
||||
this.trimToSize()
|
||||
} else {
|
||||
throw ('putCacheData() key or content or path is invalid')
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据LRU算法删除多余缓存数据
|
||||
*/
|
||||
private trimToSize() {
|
||||
while (this.size > this.maxSize) {
|
||||
var tempkey: string = this.cacheMap.getFirstKey()
|
||||
var fileSize = this.fileUtils.getFileSize(this.dirPath + tempkey)
|
||||
if (fileSize > 0) {
|
||||
this.size = this.size - fileSize
|
||||
}
|
||||
this.fileUtils.deleteFile(this.dirPath + tempkey)
|
||||
this.cacheMap.remove(tempkey)
|
||||
this.fileUtils.writeData(this.journalPath, 'remove ' + tempkey + '\n')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取key缓存数据
|
||||
*/
|
||||
getCacheDataByKey(key: string): ArrayBuffer{
|
||||
if (key == null) {
|
||||
throw new Error('key is null,checking the parameter');
|
||||
}
|
||||
key = Md5.hashStr(key)
|
||||
var path = this.dirPath + key;
|
||||
if (this.fileUtils.exist(path)) {
|
||||
var ab: ArrayBuffer = this.fileUtils.readFilePic(path)
|
||||
this.putCacheMap(key, ab.byteLength)
|
||||
this.fileUtils.writeData(this.journalPath, 'read ' + key + '\n')
|
||||
return ab
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取key缓存数据绝对路径
|
||||
*/
|
||||
getCacheFileByKey(key: string): string{
|
||||
if (key == null) {
|
||||
throw new Error('key is null,checking the parameter');
|
||||
}
|
||||
key = Md5.hashStr(key)
|
||||
if (this.dirPath.endsWith('/')) {
|
||||
this.dirPath = this.dirPath
|
||||
} else {
|
||||
this.dirPath = this.dirPath + '/'
|
||||
}
|
||||
var path = this.dirPath + key;
|
||||
if (this.fileUtils.exist(path)) {
|
||||
this.fileUtils.writeData(this.journalPath, 'read ' + key + '\n')
|
||||
return path
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除key缓存数据
|
||||
*/
|
||||
deleteCacheDataBykey(key: string): DiskCacheEntry{
|
||||
if (key == null) {
|
||||
throw new Error('key is null,checking the parameter');
|
||||
}
|
||||
key = Md5.hashStr(key)
|
||||
var path = this.dirPath + key;
|
||||
if (this.fileUtils.exist(path)) {
|
||||
var ab = this.fileUtils.readFilePic(path)
|
||||
this.size = this.size - ab.byteLength
|
||||
this.cacheMap.remove(key)
|
||||
this.fileUtils.writeData(this.journalPath, 'remove ' + key + '\n')
|
||||
this.fileUtils.deleteFile(path)
|
||||
}
|
||||
return this.cacheMap.get(key)
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有disk缓存数据
|
||||
*/
|
||||
cleanCacheData() {
|
||||
var length = this.cacheMap.size()
|
||||
for (var index = 0; index < length; index++) {
|
||||
this.fileUtils.deleteFile(this.dirPath + this.cacheMap[index])
|
||||
}
|
||||
this.fileUtils.deleteFile(this.journalPath)
|
||||
this.cacheMap.clear()
|
||||
this.size = 0
|
||||
}
|
||||
|
||||
/**
|
||||
* 空字符串判断
|
||||
*/
|
||||
private isNull(str: string): boolean{
|
||||
if (!str || Object.keys(str).length == 0) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
foreachDiskLruCache(fn){
|
||||
this.cacheMap.each(fn)
|
||||
}
|
||||
|
||||
}
|
|
@ -179,26 +179,6 @@ export class FileUtils {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取media的资源文件
|
||||
*/
|
||||
readMediaPic() {
|
||||
resmgr.getResourceManager()
|
||||
.then(result => {
|
||||
result.getMediaBase64($r('app.media.icon')
|
||||
.id)
|
||||
.then(data => {
|
||||
console.error("FileUtils - readPic data = " + data)
|
||||
data = data.replace("data:image/png;base64,", "")
|
||||
console.error("FileUtils - readPic this.data = " + data)
|
||||
this.base64Str = data
|
||||
console.error("FileUtils - readPic this.base64Str = " + this.base64Str)
|
||||
})
|
||||
.catch(err => {
|
||||
console.log("FileUtils - readPic err" + JSON.stringify(err));
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* stream式读取
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import{DiskStrategy} from '../../diskstrategy/DiskStrategy'
|
||||
import{DataSrc} from '../../diskstrategy/DataSrc'
|
||||
import{EncodeStrategy} from '../../diskstrategy/EncodeStrategy'
|
||||
import { DiskStrategy } from '../../diskstrategy/DiskStrategy'
|
||||
import { DataSrc } from '../../diskstrategy/DataSrc'
|
||||
import { EncodeStrategy } from '../../diskstrategy/EncodeStrategy'
|
||||
|
||||
export class ALL implements DiskStrategy {
|
||||
getName(): string{
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {DiskLruCache} from "../cache/DiskLruCache"
|
||||
import {LruCache} from "../cache/LruCache"
|
||||
import { DiskLruCache } from "@ohos/disklrucache"
|
||||
import { LruCache } from "../cache/LruCache"
|
||||
import {EngineKeyFactories} from "../cache/key/EngineKeyFactories"
|
||||
import {RequestOption} from "../imageknife/RequestOption"
|
||||
import {AsyncCallback} from "../imageknife/interface/asynccallback"
|
||||
|
@ -35,6 +35,8 @@ import featureAbility from '@ohos.ability.featureAbility';
|
|||
import {CompressBuilder} from "../imageknife/compress/CompressBuilder"
|
||||
|
||||
export class ImageKnife {
|
||||
static readonly SEPARATOR: string = '/'
|
||||
private imageKnifeContext;
|
||||
private memoryCache: LruCache<string, any>;
|
||||
private diskMemoryCache: DiskLruCache;
|
||||
private dataFetch: IDataFetch;
|
||||
|
@ -46,17 +48,47 @@ export class ImageKnife {
|
|||
private runningRequest: Array<RequestOption>;
|
||||
private pendingRequest: Array<RequestOption>;
|
||||
private fileTypeUtil: FileTypeUtil; // 通用文件格式辨别
|
||||
private diskCacheFolder: string = "ImageKnifeDiskCache"
|
||||
private svgAndGifFolder: string = "svgAndGifFolder"; // svg和gif的文件路径地址
|
||||
private svgAndGifCommitFile: string = "svgAndGifCommitFile" // svg和gif提交记录
|
||||
|
||||
private defaultListener:AsyncCallback<ImageKnifeData>; // 全局监听器
|
||||
private defaultListener: AsyncCallback<ImageKnifeData>; // 全局监听器
|
||||
|
||||
private constructor(imgCtx) {
|
||||
this.imageKnifeContext = imgCtx;
|
||||
|
||||
// 构造方法传入size 为保存文件个数
|
||||
this.memoryCache = new LruCache<string, any>(100);
|
||||
|
||||
// 创建disk缓存 传入的size 为多少比特 比如20KB 传入20*1024
|
||||
this.diskMemoryCache = DiskLruCache.create(this.imageKnifeContext.filesDir + ImageKnife.SEPARATOR + this.diskCacheFolder, 30 * 1024 * 1024);
|
||||
|
||||
// 创建网络下载能力
|
||||
this.dataFetch = new DownloadClient();
|
||||
|
||||
// 创建本地数据解析能力
|
||||
this.resourceFetch = new ParseResClient();
|
||||
|
||||
// 初始化本地 文件保存
|
||||
this.filesPath = this.imageKnifeContext.filesDir;
|
||||
this.initSvgAndGifEnvironment();
|
||||
|
||||
this.runningRequest = new Array();
|
||||
this.pendingRequest = new Array();
|
||||
|
||||
// 通用文件格式识别初始化
|
||||
this.fileTypeUtil = new FileTypeUtil();
|
||||
}
|
||||
|
||||
getMemoryCache(): LruCache<string, any>{
|
||||
return this.memoryCache;
|
||||
}
|
||||
|
||||
setMemoryCache(lrucache: LruCache<string, any>){
|
||||
this.memoryCache = lrucache;
|
||||
public static with(context): ImageKnife{
|
||||
if (!this.sInstance) {
|
||||
this.sInstance = new ImageKnife(context);
|
||||
}
|
||||
return this.sInstance;
|
||||
}
|
||||
|
||||
getDiskMemoryCache(): DiskLruCache{
|
||||
|
@ -81,46 +113,18 @@ export class ImageKnife {
|
|||
this.svgAndGifFolder = folderPath;
|
||||
}
|
||||
|
||||
getDefaultListener(){
|
||||
getImageKnifeContext() {
|
||||
return this.imageKnifeContext;
|
||||
}
|
||||
|
||||
setMemoryCache(lrucache: LruCache<string, any>) {
|
||||
this.memoryCache = lrucache;
|
||||
}
|
||||
|
||||
getDefaultListener() {
|
||||
return this.defaultListener;
|
||||
}
|
||||
|
||||
setDefaultListener(newDefaultListener:AsyncCallback<ImageKnifeData>){
|
||||
this.defaultListener = newDefaultListener;
|
||||
}
|
||||
|
||||
private constructor() {
|
||||
|
||||
// 构造方法传入size 为保存文件个数
|
||||
this.memoryCache = new LruCache<string, any>(100);
|
||||
|
||||
// 创建disk缓存 传入的size 为多少比特 比如20KB 传入20*1024
|
||||
this.diskMemoryCache = new DiskLruCache(30 * 1024 * 1024);
|
||||
|
||||
// 创建网络下载能力
|
||||
this.dataFetch = new DownloadClient();
|
||||
|
||||
// 创建本地数据解析能力
|
||||
this.resourceFetch = new ParseResClient();
|
||||
|
||||
// 初始化本地 文件保存
|
||||
featureAbility.getContext()
|
||||
.getFilesDir()
|
||||
.then((data) => {
|
||||
this.filesPath = data
|
||||
this.initSvgAndGifEnvironment();
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('ImageKnife Failed to obtain the filesPath directory. Cause:' + error.message);
|
||||
})
|
||||
|
||||
this.runningRequest = new Array();
|
||||
this.pendingRequest = new Array();
|
||||
|
||||
// 通用文件格式识别初始化
|
||||
this.fileTypeUtil = new FileTypeUtil();
|
||||
}
|
||||
|
||||
private initSvgAndGifEnvironment() {
|
||||
let folderExist = FileUtils.getInstance().existFolder(this.filesPath + "/" + this.svgAndGifFolder)
|
||||
let fileExist =
|
||||
|
@ -149,11 +153,8 @@ export class ImageKnife {
|
|||
|
||||
private static sInstance: ImageKnife;
|
||||
|
||||
public static with(): ImageKnife{
|
||||
if (!this.sInstance) {
|
||||
this.sInstance = new ImageKnife();
|
||||
}
|
||||
return this.sInstance;
|
||||
setDefaultListener(newDefaultListener: AsyncCallback<ImageKnifeData>) {
|
||||
this.defaultListener = newDefaultListener;
|
||||
}
|
||||
|
||||
public compressBuilder(): CompressBuilder{
|
||||
|
@ -178,15 +179,15 @@ export class ImageKnife {
|
|||
}
|
||||
|
||||
// 替代原来的DiskLruCache
|
||||
public replaceDiskLruCache(size:number){
|
||||
this.diskMemoryCache = new DiskLruCache(size);
|
||||
public replaceDiskLruCache(size:number) {
|
||||
// this.diskMemoryCache = DiskLruCache.create(this.imageKnifeContext.filesDir+ImageKnife.SEPARATOR+this.diskCacheFolder, size);
|
||||
|
||||
if(this.diskMemoryCache.cacheMap.size() <= 0) {
|
||||
this.diskMemoryCache = new DiskLruCache(size);
|
||||
}else{
|
||||
let newDiskLruCache = new DiskLruCache(size);
|
||||
if (this.diskMemoryCache.getCacheMap().size() <= 0) {
|
||||
this.diskMemoryCache = DiskLruCache.create(this.imageKnifeContext.filesDir + ImageKnife.SEPARATOR + this.diskCacheFolder, size);
|
||||
} else {
|
||||
let newDiskLruCache = DiskLruCache.create(this.imageKnifeContext.filesDir + ImageKnife.SEPARATOR + this.diskCacheFolder, size);
|
||||
this.diskMemoryCache.foreachDiskLruCache(function (value, key, map) {
|
||||
newDiskLruCache.putCacheData(key, value, null);
|
||||
newDiskLruCache.set(key, value);
|
||||
})
|
||||
this.diskMemoryCache = newDiskLruCache;
|
||||
}
|
||||
|
|
|
@ -178,23 +178,11 @@ export struct ImageKnifeComponent {
|
|||
}
|
||||
// imageknife 第一次启动和数据刷新后重新发送请求
|
||||
imageKnifeExecute() {
|
||||
|
||||
if(ImageKnife){
|
||||
}else{
|
||||
ImageKnife = globalThis.exports.default.data.imageKnife;
|
||||
}
|
||||
|
||||
if(ImageKnife){
|
||||
}else{
|
||||
console.log('ImageKnife Singleton Initialization Not Completed!')
|
||||
}
|
||||
|
||||
let request = new RequestOption();
|
||||
this.configNecessary(request);
|
||||
this.configCacheStrategy(request);
|
||||
this.configDisplay(request);
|
||||
|
||||
ImageKnife.call(request);
|
||||
globalThis.ImageKnife.call(request);
|
||||
}
|
||||
|
||||
imageKnifeChangeSource(data:ImageKnifeData) {
|
||||
|
@ -341,8 +329,7 @@ export struct ImageKnifeComponent {
|
|||
}
|
||||
}
|
||||
|
||||
var ImageKnife;
|
||||
var defaultTemp = globalThis.exports.default
|
||||
if (defaultTemp != undefined) {
|
||||
ImageKnife = defaultTemp.data.imageKnife;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -369,19 +369,8 @@ export class RequestOption {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(ImageKnife){
|
||||
}else{
|
||||
ImageKnife = globalThis.exports.default.data.imageKnife;
|
||||
}
|
||||
|
||||
if(ImageKnife){
|
||||
}else{
|
||||
console.log('ImageKnife Singleton Initialization Not Completed!')
|
||||
}
|
||||
|
||||
// 加载成功之后
|
||||
ImageKnife.removeRunning(this);
|
||||
globalThis.ImageKnife.removeRunning(this);
|
||||
}
|
||||
|
||||
loadError(err) {
|
||||
|
@ -396,25 +385,9 @@ export class RequestOption {
|
|||
this.errorholderFunc(this.errorholderData)
|
||||
}
|
||||
}
|
||||
|
||||
// 加载失败之后
|
||||
if(ImageKnife){
|
||||
}else{
|
||||
ImageKnife = globalThis.exports.default.data.imageKnife;
|
||||
}
|
||||
|
||||
if(ImageKnife){
|
||||
}else{
|
||||
console.log('ImageKnife Singleton Initialization Not Completed!')
|
||||
}
|
||||
|
||||
ImageKnife.removeRunning(this);
|
||||
globalThis.ImageKnife.removeRunning(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var ImageKnife;
|
||||
var defaultTemp = globalThis.exports.default
|
||||
if (defaultTemp != undefined) {
|
||||
ImageKnife = defaultTemp.data.imageKnife;
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@ import fileio from '@ohos.fileio';
|
|||
import {CompressAdapter} from '../compress/provider/CompressAdapter'
|
||||
import {DataStringPathProvider} from '../compress/provider/DataStringPathProvider'
|
||||
import {RecourseProvider} from '../compress/provider/RecourseProvider'
|
||||
import featureability from '@ohos.ability.featureAbility'
|
||||
import {Engine} from '../compress/Engine'
|
||||
import { Engine } from '../compress/Engine'
|
||||
import { ImageKnife } from '../ImageKnife'
|
||||
|
||||
export class CompressBuilder {
|
||||
private _mTargetDir: string;
|
||||
|
@ -106,10 +106,11 @@ export class CompressBuilder {
|
|||
|
||||
public async get():Promise<string> {
|
||||
if (!this._mTargetDir) {
|
||||
let path = await featureability.getContext().getFilesDir();
|
||||
let context = globalThis.ImageKnife.getImageKnifeContext();
|
||||
let path = context.filesDir;
|
||||
var timestamp = (new Date()).valueOf();
|
||||
this._outFilePath = path + "/compress/" + timestamp + (Math.random() * 100).toFixed(0) + ".jpg";
|
||||
let result =await this.startAsyncCompress();
|
||||
let result = await this.startAsyncCompress();
|
||||
return result;
|
||||
} else {
|
||||
let result =await this.startAsyncCompress();
|
||||
|
@ -200,15 +201,9 @@ export class CompressBuilder {
|
|||
}
|
||||
|
||||
private getImageCacheFile() {
|
||||
featureability.getContext()
|
||||
.getFilesDir()
|
||||
.then(path => {
|
||||
var timestamp = (new Date()).valueOf();
|
||||
this._outFilePath = path + "/compress/" + timestamp + (Math.random() * 100).toFixed(0) + ".jpg";
|
||||
this.startCompress();
|
||||
})
|
||||
.catch(error => {
|
||||
throw new Error("getImageCacheFile happened error:" + JSON.stringify(error));
|
||||
})
|
||||
let context = globalThis.ImageKnife.getImageKnifeContext();
|
||||
var timestamp = (new Date()).valueOf();
|
||||
this._outFilePath = context.filesDir + "/compress/" + timestamp + (Math.random() * 100).toFixed(0) + ".jpg";
|
||||
this.startCompress();
|
||||
}
|
||||
}
|
|
@ -70,7 +70,6 @@ export class Engine {
|
|||
}
|
||||
|
||||
compress() {
|
||||
console.info("asasd compress()")
|
||||
if (this.mCompressAdapter instanceof DataStringPathProvider) {
|
||||
// file
|
||||
this.mCompressAdapter.openInternal((buffer) => {
|
||||
|
@ -90,7 +89,7 @@ export class Engine {
|
|||
var height = info.size.height;
|
||||
var width = info.size.width;
|
||||
var computeSize = this.computeSize(width, height);
|
||||
console.info("asasd compress computeSize:" + computeSize);
|
||||
console.info("Engine compress computeSize:" + computeSize);
|
||||
let options = {
|
||||
editable: true,
|
||||
sampleSize: computeSize,
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
*/
|
||||
|
||||
import {CompressAdapter, PixelMapFormat} from "../provider/CompressAdapter"
|
||||
import resmgr from '@ohos.resourceManager'
|
||||
import {CompressDataListener} from "../listener/CompressDataListener"
|
||||
import {FileTypeUtil} from '../../../imageknife/utils/FileTypeUtil'
|
||||
|
||||
|
@ -43,20 +42,18 @@ export class RecourseProvider extends CompressAdapter {
|
|||
if (!this._mResourceData) {
|
||||
throw Error("compress resource is empty");
|
||||
}
|
||||
resmgr.getResourceManager()
|
||||
.then(result => {
|
||||
result.getMedia(this._mResourceData
|
||||
.id)
|
||||
.then(data => {
|
||||
let buffer = this.uint8ArrayToBuffer(data);
|
||||
let fileTypeUtil = new FileTypeUtil()
|
||||
this._mPixelMapHeader = fileTypeUtil.getFileType(buffer);
|
||||
callback(buffer);
|
||||
globalThis.ImageKnife.getImageKnifeContext().resourceManager
|
||||
.getMedia(this._mResourceData.id)
|
||||
.then(data => {
|
||||
let buffer = this.uint8ArrayToBuffer(data);
|
||||
let fileTypeUtil = new FileTypeUtil()
|
||||
this._mPixelMapHeader = fileTypeUtil.getFileType(buffer);
|
||||
callback(buffer);
|
||||
})
|
||||
.catch(err => {
|
||||
.catch(err => {
|
||||
console.log("RecourseProvider openInternal err" + JSON.stringify(err));
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
getPixelMapFormat(): PixelMapFormat{
|
||||
|
|
|
@ -13,13 +13,12 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {AsyncTransform} from "../transform/AsyncTransform"
|
||||
import { CropCallback } from './CropCallback'
|
||||
import image from "@ohos.multimedia.image"
|
||||
import {TransformUtils} from "../transform/TransformUtils"
|
||||
|
||||
export namespace Crop {
|
||||
|
||||
export function crop(buf: ArrayBuffer, x: number, y: number, cropWidth: number, cropHeight: number, func?: AsyncTransform<PixelMap>, colorRatio?: number) {
|
||||
export function crop(buf: ArrayBuffer, x: number, y: number, cropWidth: number, cropHeight: number, func?: CropCallback<PixelMap>, colorRatio?: number) {
|
||||
if (!buf || buf.byteLength <= 0) {
|
||||
console.log("Crop buf is empty");
|
||||
if (func) {
|
||||
|
@ -28,7 +27,7 @@ export namespace Crop {
|
|||
return;
|
||||
}
|
||||
var imageSource = image.createImageSource(buf as any);
|
||||
TransformUtils.getPixelMapSize(imageSource, (error, size: {
|
||||
getPixelMapSize(imageSource, (error, size: {
|
||||
width: number,
|
||||
height: number
|
||||
}) => {
|
||||
|
@ -72,7 +71,7 @@ export namespace Crop {
|
|||
})
|
||||
}
|
||||
|
||||
async function colorRatioPixelMap(data: any, width: number, height: number, colorRatio: number, func?: AsyncTransform<PixelMap>) {
|
||||
async function colorRatioPixelMap(data: any, width: number, height: number, colorRatio: number, func?: CropCallback<PixelMap>) {
|
||||
if (!data) {
|
||||
func("colorRatio pixelMap is null", null);
|
||||
return;
|
||||
|
@ -94,4 +93,23 @@ export namespace Crop {
|
|||
await writePromise;
|
||||
func("", data);
|
||||
}
|
||||
|
||||
|
||||
function getPixelMapSize(imageSource: any, func: CropCallback<{
|
||||
width: number,
|
||||
height: number
|
||||
}>) {
|
||||
if (!imageSource) {
|
||||
return;
|
||||
}
|
||||
imageSource.getImageInfo((err, value) => {
|
||||
if (err) {
|
||||
func(err, null)
|
||||
return;
|
||||
}
|
||||
var pWidth = value.size.width;
|
||||
var pHeight = value.size.height;
|
||||
func('', { width: pWidth, height: pHeight });
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
export interface CropCallback<T> {
|
||||
(err, data: T)
|
||||
}
|
|
@ -0,0 +1,889 @@
|
|||
import image from "@ohos.multimedia.image"
|
||||
import { Crop } from './Crop'
|
||||
import { CropCallback } from './CropCallback'
|
||||
|
||||
@Component
|
||||
struct PixelMapCrop {
|
||||
@Watch('watchOptions') @State options: PixelMapCrop.Options = new PixelMapCrop.Options();
|
||||
@Watch('watchCropTap') @Prop cropTap: boolean;
|
||||
@State bWidth: number = 0;
|
||||
@State bHeight: number = 0;
|
||||
@State cWidth: number = 0;
|
||||
@State cHeight: number = 0;
|
||||
downX: number = 0;
|
||||
downY: number = 0;
|
||||
moveX: number = 0;
|
||||
moveY: number = 0;
|
||||
lastMoveX: number = 0;
|
||||
lastMoveY: number = 0;
|
||||
// 裁剪4个角区域 下标0和1左上点 下标2和3右下点
|
||||
leftTopArea: number[] = [0, 0, 0, 0]
|
||||
leftBottomArea: number[] = [0, 0, 0, 0]
|
||||
rightTopArea: number[] = [0, 0, 0, 0]
|
||||
rightBottomArea: number[] = [0, 0, 0, 0]
|
||||
// 4个边框区域
|
||||
leftLineArea: number[] = [0, 0, 0, 0]
|
||||
topLineArea: number[] = [0, 0, 0, 0]
|
||||
rightLineArea: number[] = [0, 0, 0, 0]
|
||||
bottomLineArea: number[] = [0, 0, 0, 0]
|
||||
//四个角的点
|
||||
topLeftPoint: number[] = [0, 0]
|
||||
topRightPoint: number[] = [0, 0]
|
||||
bottomLeftPoint: number[] = [0, 0]
|
||||
bottomRightPoint: number[] = [0, 0]
|
||||
//角宽
|
||||
connerWidth: number = 4
|
||||
//边框线宽
|
||||
lineWidth: number = 2
|
||||
//内部预览细线
|
||||
gridLineWidth: number = 1
|
||||
MIN_LENGTH = this.connerWidth * 2 * 4
|
||||
isValidTouch = false;
|
||||
isTopLeftAreaTouch = false;
|
||||
isTopRightAreaTouch = false;
|
||||
isBottomLeftAreaTouch = false;
|
||||
isBottomRightAreaTouch = false;
|
||||
isTopLineAreaTouch = false;
|
||||
isLeftLineAreaTouch = false;
|
||||
isRightLineAreaTouch = false;
|
||||
isBottomLineAreaTouch = false;
|
||||
isMoveTouch = false;
|
||||
private settings: RenderingContextSettings = new RenderingContextSettings(true)
|
||||
private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
|
||||
private contextGesture: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)
|
||||
|
||||
watchOptions() {
|
||||
this.readyCrop();
|
||||
}
|
||||
|
||||
watchCropTap() {
|
||||
console.log('PMC watchCropTap callback')
|
||||
if (this.options.cropAction) {
|
||||
console.log('PMC cropAction start')
|
||||
this.options.cropAction(this.topLeftPoint, this.bottomRightPoint, this.options.pixelScale);
|
||||
}
|
||||
}
|
||||
|
||||
readyCrop() {
|
||||
if (!this.options.width || !this.options.height || !this.options.pixelBuffer || !this.options.pixelMap) {
|
||||
throw new Error('PixelMapCrop Options width must not be null & height must not be null & pixelMap must not be null & pixelBuffer must not be null ')
|
||||
return
|
||||
}
|
||||
|
||||
this.bWidth = px2vp(this.options.width);
|
||||
this.bHeight = px2vp(this.options.height);
|
||||
|
||||
this.cWidth = px2vp(this.options.pixelWidth)
|
||||
this.cHeight = px2vp(this.options.pixelHeight)
|
||||
|
||||
|
||||
this.context.drawImage(this.options.pixelMap, 0, 0)
|
||||
|
||||
|
||||
this.cropDefault();
|
||||
|
||||
this.buildCropBoxConnerArea()
|
||||
|
||||
this.buildCropBoxLineArea()
|
||||
|
||||
|
||||
this.drawCropBox();
|
||||
}
|
||||
|
||||
|
||||
//获取裁剪 初始位置
|
||||
cropDefault() {
|
||||
// 左上角 初始坐标
|
||||
this.topLeftPoint = [this.cWidth / 4.0 - this.connerWidth / 2.0, this.cHeight / 4.0 - this.connerWidth / 2.0]
|
||||
|
||||
// 右上角 初始坐标
|
||||
this.topRightPoint = [this.cWidth / 4.0 * 3.0 + this.connerWidth / 2.0, this.cHeight / 4.0 - this.connerWidth / 2.0]
|
||||
|
||||
// 左下角 初始坐标
|
||||
this.bottomLeftPoint = [this.cWidth / 4.0 - this.connerWidth / 2.0, this.cHeight / 4.0 * 3.0 + this.connerWidth / 2.0]
|
||||
|
||||
// 右下角 初始坐标
|
||||
this.bottomRightPoint = [this.cWidth / 4.0 * 3.0 + this.connerWidth / 2.0, this.cHeight / 4.0 * 3.0 + this.connerWidth / 2.0]
|
||||
}
|
||||
|
||||
buildCropBoxConnerArea() {
|
||||
// 左上角 初始区域
|
||||
this.leftTopArea = [this.topLeftPoint[0], this.topLeftPoint[1], this.topLeftPoint[0] + this.MIN_LENGTH / 2, this.topLeftPoint[1] + this.MIN_LENGTH / 2]
|
||||
// 右上角 初始区域
|
||||
this.rightTopArea = [this.topRightPoint[0] - this.MIN_LENGTH / 2, this.topRightPoint[1], this.topRightPoint[0], this.topRightPoint[1] + this.MIN_LENGTH / 2]
|
||||
// 左下角 初始区域
|
||||
this.leftBottomArea = [this.bottomLeftPoint[0], this.bottomLeftPoint[1] - this.MIN_LENGTH / 2, this.bottomLeftPoint[0] + this.MIN_LENGTH / 2, this.bottomLeftPoint[1]]
|
||||
// 右下角 初始区域
|
||||
this.rightBottomArea = [this.bottomRightPoint[0] - this.MIN_LENGTH / 2, this.bottomRightPoint[1] - this.MIN_LENGTH / 2, this.bottomRightPoint[0], this.bottomRightPoint[1]]
|
||||
}
|
||||
|
||||
buildCropBoxLineArea() {
|
||||
// 左线
|
||||
this.leftLineArea = [this.topLeftPoint[0], this.topLeftPoint[1] + this.MIN_LENGTH / 2, this.bottomLeftPoint[0] + this.MIN_LENGTH / 2, this.bottomLeftPoint[1] - this.MIN_LENGTH / 2]
|
||||
// 上线
|
||||
this.topLineArea = [this.topLeftPoint[0] + this.MIN_LENGTH / 2, this.topLeftPoint[1], this.topRightPoint[0] - this.MIN_LENGTH / 2, this.topRightPoint[1] + this.MIN_LENGTH / 2]
|
||||
// 右线
|
||||
this.rightLineArea = [this.topRightPoint[0] - this.MIN_LENGTH / 2, this.topRightPoint[1] + this.MIN_LENGTH / 2, this.bottomRightPoint[0], this.bottomRightPoint[1] - this.MIN_LENGTH / 2]
|
||||
// 下线
|
||||
this.bottomLineArea = [this.bottomLeftPoint[0] + this.MIN_LENGTH / 2, this.bottomLeftPoint[1] - this.MIN_LENGTH / 2, this.bottomRightPoint[0] - this.MIN_LENGTH / 2, this.bottomRightPoint[1]]
|
||||
}
|
||||
|
||||
|
||||
// 绘制裁剪框
|
||||
drawCropBox() {
|
||||
this.contextGesture.clearRect(0, 0, this.cWidth, this.cHeight)
|
||||
// 绘制 裁剪框内部 透明底色 外部非透明底色
|
||||
this.drawTransparentBackground();
|
||||
// 绘制网格线
|
||||
if (this.options.hasGuideLine) {
|
||||
this.drawGridLine()
|
||||
}
|
||||
// 绘制裁剪框边框线
|
||||
this.drawConnerLine()
|
||||
// 绘制裁剪框边框
|
||||
this.drawConner()
|
||||
}
|
||||
|
||||
drawTransparentBackground() {
|
||||
|
||||
this.contextGesture.fillStyle = 'rgba(0,0,0,0.8)'
|
||||
this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1])
|
||||
this.contextGesture.lineTo(this.topRightPoint[0], this.topRightPoint[1])
|
||||
this.contextGesture.lineTo(this.bottomRightPoint[0], this.bottomRightPoint[1])
|
||||
this.contextGesture.lineTo(this.bottomLeftPoint[0], this.bottomLeftPoint[1])
|
||||
this.contextGesture.closePath();
|
||||
|
||||
this.contextGesture.moveTo(0, 0)
|
||||
this.contextGesture.lineTo(0, this.cHeight)
|
||||
this.contextGesture.lineTo(this.cWidth, this.cHeight)
|
||||
this.contextGesture.lineTo(this.cWidth, 0)
|
||||
this.contextGesture.closePath();
|
||||
|
||||
this.contextGesture.fill();
|
||||
}
|
||||
|
||||
drawGridLine() {
|
||||
|
||||
this.contextGesture.lineWidth = this.gridLineWidth * px2vp(1)
|
||||
this.contextGesture.lineCap = 'square'
|
||||
this.contextGesture.strokeStyle = '#ffffff'
|
||||
|
||||
let contentW = this.topRightPoint[0] - this.topLeftPoint[0]
|
||||
let stepW = contentW / 3.0;
|
||||
|
||||
let contentH = this.bottomLeftPoint[1] - this.topLeftPoint[1]
|
||||
let stepH = contentH / 3.0;
|
||||
|
||||
// 竖线1
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.topLeftPoint[0] + stepW * 1.0, this.topLeftPoint[1])
|
||||
this.contextGesture.lineTo(this.bottomLeftPoint[0] + stepW * 1.0, this.bottomLeftPoint[1])
|
||||
this.contextGesture.stroke()
|
||||
|
||||
// 竖线2
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.topLeftPoint[0] + stepW * 2.0, this.topLeftPoint[1])
|
||||
this.contextGesture.lineTo(this.bottomLeftPoint[0] + stepW * 2.0, this.bottomLeftPoint[1])
|
||||
this.contextGesture.stroke()
|
||||
|
||||
//横线1
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1] + stepH * 1.0)
|
||||
this.contextGesture.lineTo(this.topRightPoint[0], this.topRightPoint[1] + stepH * 1.0)
|
||||
this.contextGesture.stroke()
|
||||
//横线2
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1] + stepH * 2.0)
|
||||
this.contextGesture.lineTo(this.topRightPoint[0], this.topRightPoint[1] + stepH * 2.0)
|
||||
this.contextGesture.stroke()
|
||||
}
|
||||
|
||||
// 边框
|
||||
drawConnerLine() {
|
||||
this.contextGesture.lineWidth = this.lineWidth
|
||||
this.contextGesture.lineCap = 'square'
|
||||
this.contextGesture.strokeStyle = '#aaaaaa'
|
||||
// 上框
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1])
|
||||
this.contextGesture.lineTo(this.topRightPoint[0], this.topRightPoint[1])
|
||||
this.contextGesture.stroke()
|
||||
// 左框
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1])
|
||||
this.contextGesture.lineTo(this.bottomLeftPoint[0], this.bottomLeftPoint[1])
|
||||
this.contextGesture.stroke()
|
||||
// 右框
|
||||
console.log('PMC this.topRightPoint=' + this.topRightPoint + ' this.bottomRightPoint=' + this.bottomRightPoint)
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.topRightPoint[0], this.topRightPoint[1])
|
||||
this.contextGesture.lineTo(this.bottomRightPoint[0], this.bottomRightPoint[1])
|
||||
this.contextGesture.stroke()
|
||||
// 下框
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.bottomLeftPoint[0], this.bottomLeftPoint[1])
|
||||
this.contextGesture.lineTo(this.bottomRightPoint[0], this.bottomRightPoint[1])
|
||||
this.contextGesture.stroke()
|
||||
}
|
||||
// 边框角
|
||||
drawConner() {
|
||||
this.contextGesture.lineWidth = this.connerWidth
|
||||
this.contextGesture.lineCap = 'square'
|
||||
this.contextGesture.strokeStyle = '#ffffff'
|
||||
|
||||
// 左上角
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1])
|
||||
this.contextGesture.lineTo(this.topLeftPoint[0], this.topLeftPoint[1] + this.MIN_LENGTH / 2.0)
|
||||
this.contextGesture.stroke()
|
||||
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.topLeftPoint[0], this.topLeftPoint[1])
|
||||
this.contextGesture.lineTo(this.topLeftPoint[0] + this.MIN_LENGTH / 2.0, this.topLeftPoint[1])
|
||||
this.contextGesture.stroke()
|
||||
|
||||
// 右上角
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.topRightPoint[0], this.topRightPoint[1])
|
||||
this.contextGesture.lineTo(this.topRightPoint[0], this.topRightPoint[1] + this.MIN_LENGTH / 2.0)
|
||||
this.contextGesture.stroke()
|
||||
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.topRightPoint[0], this.topRightPoint[1])
|
||||
this.contextGesture.lineTo(this.topRightPoint[0] - this.MIN_LENGTH / 2.0, this.topRightPoint[1])
|
||||
this.contextGesture.stroke()
|
||||
|
||||
// 左下角
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.bottomLeftPoint[0], this.bottomLeftPoint[1])
|
||||
this.contextGesture.lineTo(this.bottomLeftPoint[0], this.bottomLeftPoint[1] - this.MIN_LENGTH / 2.0)
|
||||
this.contextGesture.stroke()
|
||||
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.bottomLeftPoint[0], this.bottomLeftPoint[1])
|
||||
this.contextGesture.lineTo(this.bottomLeftPoint[0] + this.MIN_LENGTH / 2.0, this.bottomLeftPoint[1])
|
||||
this.contextGesture.stroke()
|
||||
|
||||
|
||||
// 右下角
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.bottomRightPoint[0], this.bottomRightPoint[1])
|
||||
this.contextGesture.lineTo(this.bottomRightPoint[0], this.bottomRightPoint[1] - this.MIN_LENGTH / 2.0)
|
||||
this.contextGesture.stroke()
|
||||
|
||||
this.contextGesture.beginPath()
|
||||
this.contextGesture.moveTo(this.bottomRightPoint[0], this.bottomRightPoint[1])
|
||||
this.contextGesture.lineTo(this.bottomRightPoint[0] - this.MIN_LENGTH / 2.0, this.bottomRightPoint[1])
|
||||
this.contextGesture.stroke()
|
||||
}
|
||||
|
||||
build() {
|
||||
Stack() {
|
||||
Canvas(this.context)
|
||||
.width(this.cWidth)
|
||||
.height(this.cHeight)
|
||||
.onReady(() => {
|
||||
}).backgroundColor(Color.Yellow)
|
||||
|
||||
Canvas(this.contextGesture)
|
||||
.width(this.cWidth)
|
||||
.height(this.cHeight)
|
||||
// .backgroundColor('#33000000')
|
||||
.onReady(() => {
|
||||
})
|
||||
.onTouch((event: TouchEvent) => {
|
||||
if (event.type === TouchType.Down) {
|
||||
// 手指按下
|
||||
this.downX = event.touches[0].x;
|
||||
this.downY = event.touches[0].y;
|
||||
|
||||
this.lastMoveX = event.touches[0].x;
|
||||
this.lastMoveY = event.touches[0].y;
|
||||
|
||||
this.belongRegion()
|
||||
|
||||
}
|
||||
if (event.type === TouchType.Up) {
|
||||
// 手指放开
|
||||
this.downX = 0;
|
||||
this.downY = 0;
|
||||
|
||||
this.moveX = 0;
|
||||
this.moveY = 0;
|
||||
|
||||
this.resetTouch();
|
||||
|
||||
}
|
||||
if (event.type === TouchType.Move) {
|
||||
// 手指移动
|
||||
this.moveX = event.touches[0].x;
|
||||
this.moveY = event.touches[0].y;
|
||||
// 每次移动的delta数据
|
||||
let dx = this.moveX - this.lastMoveX;
|
||||
let dy = this.moveY - this.lastMoveY;
|
||||
|
||||
console.log('PMC this.isTopLeftAreaTouch =' + this.isTopLeftAreaTouch + ' this.isTopRightAreaTouch =' + this.isTopRightAreaTouch
|
||||
+ ' this.isBottomLeftAreaTouch=' + this.isBottomLeftAreaTouch + ' isBottomRightAreaTouch' + this.isBottomRightAreaTouch
|
||||
+ ' dx =' + dx + ' dy =' + dy)
|
||||
|
||||
this.touchLeftTopArea(dx, dy)
|
||||
this.touchRightTopArea(dx, dy)
|
||||
this.touchLeftBottomArea(dx, dy)
|
||||
this.touchRightBottomArea(dx, dy)
|
||||
|
||||
|
||||
this.touchTopLineArea(dx, dy)
|
||||
this.touchLeftLineArea(dx, dy)
|
||||
this.touchRightLineArea(dx, dy)
|
||||
this.touchBottomLineArea(dx, dy)
|
||||
|
||||
this.touchMoveCropBox(dx, dy);
|
||||
|
||||
this.lastMoveX = event.touches[0].x
|
||||
this.lastMoveY = event.touches[0].y
|
||||
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
.width(this.bWidth)
|
||||
.height(this.bHeight)
|
||||
.padding({
|
||||
left: (this.bWidth - this.cWidth) / 2.0,
|
||||
top: (this.bHeight - this.cHeight) / 2.0,
|
||||
right: (this.bWidth - this.cWidth) / 2.0,
|
||||
bottom: (this.bHeight - this.cHeight) / 2.0
|
||||
})
|
||||
.backgroundColor(Color.Pink)
|
||||
}
|
||||
|
||||
touchLeftTopArea(dx: number, dy: number) {
|
||||
if (this.isTopLeftAreaTouch) {
|
||||
let boarderLeft = this.topLeftPoint[0] + dx
|
||||
|
||||
if (boarderLeft < 0) {
|
||||
dx = 0 - this.topLeftPoint[0];
|
||||
}
|
||||
|
||||
let boarderTop = this.topLeftPoint[1] + dy
|
||||
if (boarderTop < 0) {
|
||||
dy = 0 - this.topLeftPoint[1]
|
||||
}
|
||||
|
||||
let boarderRight = this.topLeftPoint[0] + dx
|
||||
if (boarderRight > this.topRightPoint[0] - this.MIN_LENGTH) {
|
||||
dx = this.topRightPoint[0] - this.MIN_LENGTH - this.topLeftPoint[0]
|
||||
}
|
||||
|
||||
let boarderBottom = this.topLeftPoint[1] + dy
|
||||
if (boarderBottom > this.bottomLeftPoint[1] - this.MIN_LENGTH) {
|
||||
dy = this.bottomLeftPoint[1] - this.MIN_LENGTH - this.topLeftPoint[1]
|
||||
}
|
||||
|
||||
|
||||
this.topLeftPoint[0] = this.topLeftPoint[0] + dx;
|
||||
this.topLeftPoint[1] = this.topLeftPoint[1] + dy;
|
||||
|
||||
this.topRightPoint[1] = this.topRightPoint[1] + dy;
|
||||
|
||||
this.bottomLeftPoint[0] = this.bottomLeftPoint[0] + dx;
|
||||
|
||||
this.buildCropBoxConnerArea();
|
||||
this.buildCropBoxLineArea();
|
||||
this.drawCropBox();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
touchRightTopArea(dx: number, dy: number) {
|
||||
if (this.isTopRightAreaTouch) {
|
||||
let boarderLeft = this.topRightPoint[0] + dx
|
||||
|
||||
if (boarderLeft < this.topLeftPoint[0] + this.MIN_LENGTH) {
|
||||
dx = this.topLeftPoint[0] + this.MIN_LENGTH - this.topRightPoint[0];
|
||||
}
|
||||
|
||||
let boarderTop = this.topRightPoint[1] + dy
|
||||
if (boarderTop < 0) {
|
||||
dy = 0 - this.topRightPoint[1]
|
||||
}
|
||||
|
||||
let boarderRight = this.topRightPoint[0] + dx
|
||||
if (boarderRight > this.cWidth) {
|
||||
dx = this.cWidth - this.topRightPoint[0]
|
||||
}
|
||||
|
||||
let boarderBottom = this.topRightPoint[1] + dy
|
||||
if (boarderBottom > this.bottomRightPoint[1] - this.MIN_LENGTH) {
|
||||
dy = this.bottomRightPoint[1] - this.MIN_LENGTH - this.topLeftPoint[1]
|
||||
}
|
||||
|
||||
|
||||
this.topRightPoint[0] = this.topRightPoint[0] + dx;
|
||||
this.topRightPoint[1] = this.topRightPoint[1] + dy;
|
||||
|
||||
this.topLeftPoint[1] = this.topLeftPoint[1] + dy;
|
||||
this.bottomRightPoint[0] = this.bottomRightPoint[0] + dx;
|
||||
|
||||
this.buildCropBoxConnerArea();
|
||||
this.buildCropBoxLineArea();
|
||||
this.drawCropBox();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
touchLeftBottomArea(dx: number, dy: number) {
|
||||
if (this.isBottomLeftAreaTouch) {
|
||||
let boarderLeft = this.bottomLeftPoint[0] + dx
|
||||
|
||||
if (boarderLeft < 0) {
|
||||
dx = 0 - this.bottomLeftPoint[0];
|
||||
}
|
||||
|
||||
let boarderTop = this.bottomLeftPoint[1] + dy
|
||||
if (boarderTop < this.topLeftPoint[1] + this.MIN_LENGTH) {
|
||||
dy = this.topLeftPoint[1] + this.MIN_LENGTH - this.bottomLeftPoint[1]
|
||||
}
|
||||
|
||||
let boarderRight = this.bottomLeftPoint[0] + dx
|
||||
if (boarderRight > this.bottomRightPoint[0] - this.MIN_LENGTH) {
|
||||
dx = this.bottomRightPoint[0] - this.MIN_LENGTH - this.bottomLeftPoint[0]
|
||||
}
|
||||
|
||||
let boarderBottom = this.bottomLeftPoint[1] + dy
|
||||
if (boarderBottom > this.cHeight) {
|
||||
dy = this.cHeight - this.bottomLeftPoint[1]
|
||||
}
|
||||
|
||||
|
||||
this.bottomLeftPoint[0] = this.bottomLeftPoint[0] + dx;
|
||||
this.bottomLeftPoint[1] = this.bottomLeftPoint[1] + dy;
|
||||
|
||||
this.topLeftPoint[0] = this.topLeftPoint[0] + dx;
|
||||
this.bottomRightPoint[1] = this.bottomRightPoint[1] + dy;
|
||||
|
||||
this.buildCropBoxConnerArea();
|
||||
this.buildCropBoxLineArea();
|
||||
this.drawCropBox();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
touchRightBottomArea(dx: number, dy: number) {
|
||||
if (this.isBottomRightAreaTouch) {
|
||||
let boarderLeft = this.bottomRightPoint[0] + dx
|
||||
|
||||
if (boarderLeft < this.bottomLeftPoint[0] + this.MIN_LENGTH) {
|
||||
dx = this.bottomLeftPoint[0] + this.MIN_LENGTH - this.bottomRightPoint[0];
|
||||
}
|
||||
|
||||
let boarderTop = this.bottomRightPoint[1] + dy
|
||||
if (boarderTop < this.topRightPoint[1] + this.MIN_LENGTH) {
|
||||
dy = this.topRightPoint[1] + this.MIN_LENGTH - this.bottomRightPoint[1]
|
||||
}
|
||||
|
||||
let boarderRight = this.bottomRightPoint[0] + dx
|
||||
if (boarderRight > this.cWidth) {
|
||||
dx = this.cWidth - this.bottomRightPoint[0]
|
||||
}
|
||||
|
||||
let boarderBottom = this.bottomRightPoint[1] + dy
|
||||
if (boarderBottom > this.cHeight) {
|
||||
dy = this.cHeight - this.bottomRightPoint[1]
|
||||
}
|
||||
|
||||
|
||||
this.bottomRightPoint[0] = this.bottomRightPoint[0] + dx;
|
||||
this.bottomRightPoint[1] = this.bottomRightPoint[1] + dy;
|
||||
|
||||
this.bottomLeftPoint[1] = this.bottomLeftPoint[1] + dy;
|
||||
this.topRightPoint[0] = this.topRightPoint[0] + dx;
|
||||
|
||||
this.buildCropBoxConnerArea();
|
||||
this.buildCropBoxLineArea();
|
||||
this.drawCropBox();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
touchTopLineArea(dx: number, dy: number) {
|
||||
|
||||
if (this.isTopLineAreaTouch) {
|
||||
|
||||
|
||||
let boarderTop = this.topLeftPoint[1] + dy
|
||||
if (boarderTop < 0) {
|
||||
dy = 0 - this.topLeftPoint[1]
|
||||
}
|
||||
|
||||
let boarderBottom = this.topLeftPoint[1] + dy
|
||||
if (boarderBottom > this.bottomLeftPoint[1] - this.MIN_LENGTH) {
|
||||
dy = this.bottomLeftPoint[1] - this.MIN_LENGTH - this.topLeftPoint[1]
|
||||
}
|
||||
|
||||
|
||||
this.topLeftPoint[1] = this.topLeftPoint[1] + dy;
|
||||
|
||||
this.topRightPoint[1] = this.topRightPoint[1] + dy;
|
||||
|
||||
|
||||
this.buildCropBoxConnerArea();
|
||||
this.buildCropBoxLineArea();
|
||||
this.drawCropBox();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
touchBottomLineArea(dx: number, dy: number) {
|
||||
|
||||
if (this.isBottomLineAreaTouch) {
|
||||
|
||||
let boarderTop = this.bottomLeftPoint[1] + dy
|
||||
if (boarderTop < this.topLeftPoint[1] + this.MIN_LENGTH) {
|
||||
dy = this.topLeftPoint[1] + this.MIN_LENGTH - this.bottomLeftPoint[1]
|
||||
}
|
||||
|
||||
let boarderBottom = this.bottomLeftPoint[1] + dy
|
||||
if (boarderBottom > this.cHeight) {
|
||||
dy = this.cHeight - this.bottomLeftPoint[1]
|
||||
}
|
||||
|
||||
this.bottomLeftPoint[1] = this.bottomLeftPoint[1] + dy;
|
||||
this.bottomRightPoint[1] = this.bottomRightPoint[1] + dy;
|
||||
|
||||
this.buildCropBoxConnerArea();
|
||||
this.buildCropBoxLineArea();
|
||||
this.drawCropBox();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
touchLeftLineArea(dx: number, dy: number) {
|
||||
|
||||
if (this.isLeftLineAreaTouch) {
|
||||
let boarderLeft = this.topLeftPoint[0] + dx
|
||||
if (boarderLeft < 0) {
|
||||
dx = 0 - this.topLeftPoint[0];
|
||||
}
|
||||
|
||||
let boarderRight = this.topLeftPoint[0] + dx
|
||||
if (boarderRight > this.topRightPoint[0] - this.MIN_LENGTH) {
|
||||
dx = this.topRightPoint[0] - this.MIN_LENGTH - this.topLeftPoint[0]
|
||||
}
|
||||
|
||||
this.topLeftPoint[0] = this.topLeftPoint[0] + dx;
|
||||
this.bottomLeftPoint[0] = this.bottomLeftPoint[0] + dx;
|
||||
|
||||
|
||||
this.buildCropBoxConnerArea();
|
||||
this.buildCropBoxLineArea();
|
||||
this.drawCropBox();
|
||||
}
|
||||
}
|
||||
|
||||
touchRightLineArea(dx: number, dy: number) {
|
||||
if (this.isRightLineAreaTouch) {
|
||||
|
||||
let boarderLeft = this.topRightPoint[0] + dx
|
||||
if (boarderLeft < this.topLeftPoint[0] + this.MIN_LENGTH) {
|
||||
dx = this.topLeftPoint[0] + this.MIN_LENGTH - this.topRightPoint[0];
|
||||
}
|
||||
|
||||
let boarderRight = this.topRightPoint[0] + dx
|
||||
if (boarderRight > this.cWidth) {
|
||||
dx = this.cWidth - this.topRightPoint[0]
|
||||
}
|
||||
|
||||
this.topRightPoint[0] = this.topRightPoint[0] + dx;
|
||||
this.bottomRightPoint[0] = this.bottomRightPoint[0] + dx;
|
||||
|
||||
this.buildCropBoxConnerArea();
|
||||
this.buildCropBoxLineArea();
|
||||
this.drawCropBox();
|
||||
}
|
||||
}
|
||||
|
||||
touchMoveCropBox(dx: number, dy: number) {
|
||||
if (this.isMoveTouch) {
|
||||
let boarderLeft = this.topLeftPoint[0] + dx
|
||||
if (boarderLeft < 0) {
|
||||
dx = 0 - this.topLeftPoint[0];
|
||||
}
|
||||
|
||||
let boarderTop = this.topLeftPoint[1] + dy
|
||||
if (boarderTop < 0) {
|
||||
dy = 0 - this.topLeftPoint[1]
|
||||
}
|
||||
|
||||
let boarderRight = this.bottomRightPoint[0] + dx
|
||||
if (boarderRight > this.cWidth) {
|
||||
dx = this.cWidth - this.bottomRightPoint[0]
|
||||
}
|
||||
|
||||
let boarderBottom = this.bottomRightPoint[1] + dy
|
||||
if (boarderBottom > this.cHeight) {
|
||||
dy = this.cHeight - this.bottomRightPoint[1]
|
||||
}
|
||||
|
||||
this.topLeftPoint[0] = this.topLeftPoint[0] + dx;
|
||||
this.topLeftPoint[1] = this.topLeftPoint[1] + dy;
|
||||
|
||||
this.topRightPoint[0] = this.topRightPoint[0] + dx;
|
||||
this.topRightPoint[1] = this.topRightPoint[1] + dy;
|
||||
|
||||
this.bottomLeftPoint[0] = this.bottomLeftPoint[0] + dx;
|
||||
this.bottomLeftPoint[1] = this.bottomLeftPoint[1] + dy;
|
||||
|
||||
this.bottomRightPoint[0] = this.bottomRightPoint[0] + dx;
|
||||
this.bottomRightPoint[1] = this.bottomRightPoint[1] + dy;
|
||||
|
||||
|
||||
this.buildCropBoxConnerArea();
|
||||
this.buildCropBoxLineArea();
|
||||
this.drawCropBox();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 判断用户手指按下的点的位置
|
||||
belongRegion() {
|
||||
this.resetTouch();
|
||||
// 首先判断是否落在裁剪框默认范围内
|
||||
this.isBelongCropBox();
|
||||
console.log('PMC this.isValidTouch=' + this.isValidTouch)
|
||||
console.log('PMC downx =' + this.downX + ' downy =' + this.downY + 'this.leftTopArea =' + this.leftTopArea + ' this.leftBottomArea=' + this.leftBottomArea
|
||||
+ ' this.rightTopArea=' + this.rightTopArea + ' this.rightBottomArea=' + this.rightBottomArea);
|
||||
// 其次判断是否落在裁剪框4个角位置范围
|
||||
if (this.isValidTouch) {
|
||||
console.log('PMC C1')
|
||||
this.isTopLeftAreaTouch = this.connerBelonged(this.leftTopArea)
|
||||
console.log('PMC C2')
|
||||
this.isBottomLeftAreaTouch = this.connerBelonged(this.leftBottomArea)
|
||||
console.log('PMC C3')
|
||||
this.isTopRightAreaTouch = this.connerBelonged(this.rightTopArea)
|
||||
console.log('PMC C4')
|
||||
this.isBottomRightAreaTouch = this.connerBelonged(this.rightBottomArea)
|
||||
console.log('PMC result this.isTopLeftAreaTouch =' + this.isTopLeftAreaTouch + ' this.isTopRightAreaTouch =' + this.isTopRightAreaTouch
|
||||
+ ' this.isBottomLeftAreaTouch=' + this.isBottomLeftAreaTouch + ' isBottomRightAreaTouch' + this.isBottomRightAreaTouch)
|
||||
|
||||
// 再判断是否落在裁剪框4个边框范围
|
||||
if (!this.isTopLeftAreaTouch && !this.isBottomLeftAreaTouch && !this.isTopRightAreaTouch && !this.isBottomRightAreaTouch) {
|
||||
console.log('PMC L1')
|
||||
this.isTopLineAreaTouch = this.lineBelonged(this.topLineArea)
|
||||
console.log('PMC L2')
|
||||
this.isLeftLineAreaTouch = this.lineBelonged(this.leftLineArea)
|
||||
console.log('PMC L3')
|
||||
this.isRightLineAreaTouch = this.lineBelonged(this.rightLineArea)
|
||||
console.log('PMC L4')
|
||||
this.isBottomLineAreaTouch = this.lineBelonged(this.bottomLineArea)
|
||||
|
||||
console.log('PMC result this.isTopLineAreaTouch =' + this.isTopLineAreaTouch + ' this.isLeftLineAreaTouch =' + this.isLeftLineAreaTouch
|
||||
+ ' this.isRightLineAreaTouch=' + this.isRightLineAreaTouch + ' isBottomLineAreaTouch' + this.isBottomLineAreaTouch)
|
||||
|
||||
}
|
||||
if (!this.isTopLeftAreaTouch && !this.isBottomLeftAreaTouch && !this.isTopRightAreaTouch && !this.isBottomRightAreaTouch
|
||||
&& !this.isTopLineAreaTouch && !this.isLeftLineAreaTouch && !this.isRightLineAreaTouch && !this.isBottomLineAreaTouch
|
||||
) {
|
||||
this.belongMoveTouch();
|
||||
}
|
||||
}
|
||||
|
||||
// 最后的其他位置都是整体平移整个裁剪框
|
||||
}
|
||||
|
||||
resetTouch() {
|
||||
this.isValidTouch = false;
|
||||
|
||||
this.isTopLeftAreaTouch = false;
|
||||
this.isTopRightAreaTouch = false;
|
||||
this.isBottomLeftAreaTouch = false;
|
||||
this.isBottomRightAreaTouch = false;
|
||||
|
||||
this.isTopLineAreaTouch = false;
|
||||
this.isLeftLineAreaTouch = false;
|
||||
this.isRightLineAreaTouch = false;
|
||||
this.isBottomLineAreaTouch = false;
|
||||
|
||||
this.isMoveTouch = false;
|
||||
}
|
||||
|
||||
isBelongCropBox() {
|
||||
|
||||
let x0 = this.topLeftPoint[0];
|
||||
let y0 = this.topLeftPoint[1];
|
||||
|
||||
let x1 = this.bottomRightPoint[0];
|
||||
let y1 = this.bottomRightPoint[1];
|
||||
|
||||
if (this.downX >= x0 && this.downX <= x1 && this.downY >= y0 && this.downY <= y1) {
|
||||
this.isValidTouch = true;
|
||||
} else {
|
||||
this.isValidTouch = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
belongMoveTouch() {
|
||||
|
||||
let x0 = this.topLeftPoint[0] + this.MIN_LENGTH / 2;
|
||||
let y0 = this.topLeftPoint[1] + this.MIN_LENGTH / 2;
|
||||
|
||||
let x1 = this.bottomRightPoint[0] - this.MIN_LENGTH / 2;
|
||||
let y1 = this.bottomRightPoint[1] - this.MIN_LENGTH / 2;
|
||||
|
||||
if (this.downX > x0 && this.downX < x1 && this.downY > y0 && this.downY < y1) {
|
||||
this.isMoveTouch = true;
|
||||
} else {
|
||||
this.isMoveTouch = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
lineBelonged(area: number[]) {
|
||||
|
||||
let x0 = area[0];
|
||||
let y0 = area[1];
|
||||
|
||||
let x1 = area[2];
|
||||
let y1 = area[3];
|
||||
|
||||
if (this.downX > x0 && this.downX < x1 && this.downY > y0 && this.downY < y1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
connerBelonged(area: number[]): boolean {
|
||||
|
||||
let x0 = area[0];
|
||||
let y0 = area[1];
|
||||
|
||||
let x1 = area[2];
|
||||
let y1 = area[3];
|
||||
console.log('PMC downx=' + this.downX + ' downY' + this.downY + ' x0=' + x0 + ' y0=' + y0 + ' x1=' + x1 + ' y1=' + y1)
|
||||
if (this.downX >= x0 && this.downX <= x1 && this.downY >= y0 && this.downY <= y1) {
|
||||
console.log('PMC conner is belonged!')
|
||||
return true
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
namespace PixelMapCrop {
|
||||
|
||||
|
||||
export class Options {
|
||||
width: number;
|
||||
height: number;
|
||||
pixelMap: PixelMap;
|
||||
|
||||
// 是否需要绘制线
|
||||
hasGuideLine: boolean;
|
||||
pixelBuffer: ArrayBuffer;
|
||||
// 展示pixel宽度
|
||||
pixelWidth: number;
|
||||
// 展示pixel高度
|
||||
pixelHeight: number;
|
||||
// 缩放scale:center-inside类型缩放的比例
|
||||
pixelScale: number;
|
||||
|
||||
// 用户裁剪后的回调
|
||||
cropFunction: Function;
|
||||
|
||||
// 本地裁剪框 回调
|
||||
cropAction: Function;
|
||||
|
||||
constructor() {
|
||||
|
||||
}
|
||||
|
||||
// 裁剪动作
|
||||
setCropFunction(crop: (error, pixelmap, sx, sy) => void) {
|
||||
this.cropFunction = crop;
|
||||
|
||||
this.cropAction = (topLeftPoint, bottomRightPoint, scaleInside) => {
|
||||
let dx = vp2px(1) * topLeftPoint[0] * 1.0 / scaleInside;
|
||||
let dy = vp2px(1) * topLeftPoint[1] * 1.0 / scaleInside;
|
||||
let sx = vp2px(1) * (bottomRightPoint[0] - topLeftPoint[0]) * 1.0 / scaleInside;
|
||||
let sy = vp2px(1) * (bottomRightPoint[1] - topLeftPoint[1]) * 1.0 / scaleInside;
|
||||
Crop.crop(this.pixelBuffer, dx, dy, sx, sy, (error, pixelmap) => {
|
||||
this.cropFunction(error, pixelmap, sx, sy)
|
||||
}, 1);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
setWidth(imageWidth: number) {
|
||||
this.width = imageWidth;
|
||||
return this;
|
||||
}
|
||||
|
||||
setHeight(imageHeight: number) {
|
||||
this.height = imageHeight;
|
||||
return this;
|
||||
}
|
||||
|
||||
setGuideLine(guideLine: boolean) {
|
||||
this.hasGuideLine = guideLine;
|
||||
}
|
||||
|
||||
getGuideLine() {
|
||||
return this.hasGuideLine;
|
||||
}
|
||||
|
||||
async loadBuffer(buffer: ArrayBuffer, readyCrop: Function) {
|
||||
if (!buffer || buffer.byteLength <= 0) {
|
||||
console.log('PixelMapCrop "loadBuffer" method buf is empty');
|
||||
return;
|
||||
}
|
||||
|
||||
//数据赋值
|
||||
this.pixelBuffer = buffer;
|
||||
|
||||
let imageSource = image.createImageSource(buffer as any);
|
||||
imageSource.getImageInfo().then((imageInfo) => {
|
||||
//获取宽高
|
||||
|
||||
let scaleInside = 1;
|
||||
|
||||
if (this.width && this.height) {
|
||||
//center_inside 模式判断
|
||||
let scaleW = imageInfo.size.width / (this.width * 1.0)
|
||||
let scaleH = imageInfo.size.height / (this.height * 1.0)
|
||||
if (scaleH > 1 || scaleW > 1) {
|
||||
scaleInside = 1.0 / Math.max(scaleW, scaleH)
|
||||
}
|
||||
|
||||
} else {
|
||||
this.width = imageInfo.size.width;
|
||||
this.height = imageInfo.size.height;
|
||||
}
|
||||
this.pixelScale = scaleInside;
|
||||
this.pixelWidth = imageInfo.size.width * scaleInside;
|
||||
this.pixelHeight = imageInfo.size.height * scaleInside;
|
||||
|
||||
let options = {
|
||||
editable: true,
|
||||
rotate: 0,
|
||||
desiredSize: {
|
||||
width: imageInfo.size.width * scaleInside,
|
||||
height: imageInfo.size.height * scaleInside,
|
||||
}
|
||||
}
|
||||
imageSource.createPixelMap(options).then((pixelmap) => {
|
||||
this.pixelMap = pixelmap;
|
||||
if (readyCrop) {
|
||||
readyCrop();
|
||||
}
|
||||
})
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default PixelMapCrop;
|
|
@ -13,122 +13,107 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {IDataFetch} from "../networkmanage/IDataFetch"
|
||||
import {RequestOption} from "../RequestOption"
|
||||
import {Md5} from "../../cache/Md5"
|
||||
import{FileUtils} from "../../cache/FileUtils"
|
||||
|
||||
import { IDataFetch } from "../networkmanage/IDataFetch"
|
||||
import { RequestOption } from "../RequestOption"
|
||||
import { Md5 } from "../../cache/Md5"
|
||||
import { FileUtils } from "../../cache/FileUtils"
|
||||
import loadRequest from '@ohos.request';
|
||||
|
||||
export class DownloadClient implements IDataFetch {
|
||||
loadData(request: RequestOption, onCompleteFunction, onErrorFunction) {
|
||||
|
||||
let requestUrl = request.loadSrc as string;
|
||||
if (requestUrl.startsWith("http") || requestUrl.startsWith("https")) {
|
||||
let filename = Md5.hashStr(request.generateDataKey);
|
||||
let downloadFolder = request.getFilesPath() + "/" + request.networkCacheFolder;
|
||||
let allpath = request.getFilesPath() + "/" + request.networkCacheFolder + "/" + filename + ".img";
|
||||
let filename = Md5.hashStr(request.generateDataKey);
|
||||
let downloadFolder = request.getFilesPath() + "/" + request.networkCacheFolder;
|
||||
let allpath = request.getFilesPath() + "/" + request.networkCacheFolder + "/" + filename + ".img";
|
||||
|
||||
if (!FileUtils.getInstance().existFolder(downloadFolder)) {
|
||||
FileUtils.getInstance().createFolder(downloadFolder)
|
||||
}
|
||||
if (!FileUtils.getInstance().existFolder(downloadFolder)) {
|
||||
FileUtils.getInstance().createFolder(downloadFolder)
|
||||
}
|
||||
|
||||
if (FileUtils.getInstance().exist(allpath)) {
|
||||
FileUtils.getInstance().deleteFile(allpath)
|
||||
}
|
||||
if (FileUtils.getInstance().exist(allpath)) {
|
||||
FileUtils.getInstance().deleteFile(allpath)
|
||||
}
|
||||
|
||||
let desc = filename + ".img";
|
||||
let desc = filename + ".img";
|
||||
var downloadConfig = {
|
||||
url: (request.loadSrc as string),
|
||||
filePath: allpath,
|
||||
};
|
||||
|
||||
var downloadConfig = {
|
||||
url: (request.loadSrc as string),
|
||||
filePath: allpath,
|
||||
header: {},
|
||||
enableMetered: true,
|
||||
enableRoaming: true,
|
||||
description: desc,
|
||||
networkType: 1,
|
||||
title: filename,
|
||||
};
|
||||
let loadTask = null;
|
||||
loadRequest.download(globalThis.ImageKnife.getImageKnifeContext(), downloadConfig).then(downloadTask => {
|
||||
if (downloadTask) {
|
||||
loadTask = downloadTask;
|
||||
|
||||
let loadTask = null;
|
||||
loadRequest.download(downloadConfig, (err, downloadTask) =>{
|
||||
if(err){
|
||||
onErrorFunction(err)
|
||||
}else {
|
||||
if (downloadTask) {
|
||||
loadTask = downloadTask;
|
||||
loadTask.on('progress', (receivedSize, totalSize) => {
|
||||
let percent = Math.round(((receivedSize * 1.0) / (totalSize * 1.0)) * 100) + "%"
|
||||
if (request.progressFunc) {
|
||||
request.progressFunc(percent);
|
||||
}
|
||||
});
|
||||
|
||||
loadTask.on('progress', (err, receivedSize, totalSize) => {
|
||||
let percent = Math.round(((receivedSize * 1.0) / (totalSize * 1.0)) * 100) + "%"
|
||||
if (request.progressFunc) {
|
||||
request.progressFunc(percent);
|
||||
}
|
||||
});
|
||||
loadTask.on('complete', () => {
|
||||
let downloadPath = allpath;
|
||||
request.downloadFilePath = downloadPath;
|
||||
let arraybuffer = FileUtils.getInstance().readFilePic(downloadPath)
|
||||
onCompleteFunction(arraybuffer);
|
||||
FileUtils.getInstance().deleteFile(downloadPath);
|
||||
|
||||
loadTask.on('complete', () => {
|
||||
let downloadPath = allpath;
|
||||
request.downloadFilePath = downloadPath;
|
||||
let arraybuffer = FileUtils.getInstance().readFilePic(downloadPath)
|
||||
onCompleteFunction(arraybuffer);
|
||||
FileUtils.getInstance().deleteFile(downloadPath);
|
||||
loadTask.off('complete', () => {
|
||||
|
||||
loadTask.off('complete', () => {
|
||||
loadTask = null;
|
||||
})
|
||||
})
|
||||
|
||||
loadTask.off('pause', () => {
|
||||
})
|
||||
loadTask.off('pause', () => {
|
||||
})
|
||||
|
||||
loadTask.off('remove', () => {
|
||||
})
|
||||
loadTask.off('remove', () => {
|
||||
})
|
||||
|
||||
loadTask.off('progress', () => {
|
||||
})
|
||||
loadTask.off('progress', () => {
|
||||
})
|
||||
|
||||
loadTask.off('fail', () => {
|
||||
})
|
||||
})
|
||||
|
||||
loadTask.on('pause', () => {
|
||||
})
|
||||
|
||||
loadTask.on('remove', () => {
|
||||
})
|
||||
|
||||
loadTask.on('fail', (err) => {
|
||||
onErrorFunction('DownloadClient Download task fail err =' + err)
|
||||
if (loadTask) {
|
||||
loadTask.remove().then(result => {
|
||||
loadTask.off('complete', () => {
|
||||
})
|
||||
|
||||
loadTask.off('pause', () => {
|
||||
})
|
||||
|
||||
loadTask.off('remove', () => {
|
||||
})
|
||||
|
||||
loadTask.off('progress', () => {
|
||||
})
|
||||
|
||||
loadTask.off('fail', () => {
|
||||
})
|
||||
loadTask = null
|
||||
}).catch(err => {
|
||||
loadTask = null;
|
||||
console.log('DownloadClient Download task fail err =' + err);
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
} else {
|
||||
onErrorFunction('DownloadClient downloadTask dismiss!')
|
||||
}
|
||||
}
|
||||
loadTask.off('fail', () => {
|
||||
})
|
||||
loadTask = null;
|
||||
})
|
||||
|
||||
} else {
|
||||
onErrorFunction("DownloadClient 暂不支持除http之外的uri加载")
|
||||
}
|
||||
loadTask.on('pause', () => {
|
||||
})
|
||||
|
||||
loadTask.on('remove', () => {
|
||||
})
|
||||
|
||||
loadTask.on('fail', (err) => {
|
||||
onErrorFunction('DownloadClient Download task fail err =' + err)
|
||||
if (loadTask) {
|
||||
loadTask.remove().then(result => {
|
||||
loadTask.off('complete', () => {
|
||||
})
|
||||
|
||||
loadTask.off('pause', () => {
|
||||
})
|
||||
|
||||
loadTask.off('remove', () => {
|
||||
})
|
||||
|
||||
loadTask.off('progress', () => {
|
||||
})
|
||||
|
||||
loadTask.off('fail', () => {
|
||||
})
|
||||
loadTask = null
|
||||
}).catch(err => {
|
||||
loadTask = null;
|
||||
console.log('DownloadClient Download task fail err =' + err);
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
} else {
|
||||
onErrorFunction('DownloadClient downloadTask dismiss!')
|
||||
}
|
||||
}).catch((err) => {
|
||||
onErrorFunction(err)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -16,7 +16,6 @@ import {UPNG} from '../pngj/UPNG';
|
|||
import {PngCallback} from '../pngj/PngCallback';
|
||||
import image from '@ohos.multimedia.image';
|
||||
import resourceManager from '@ohos.resourceManager';
|
||||
import featureability from '@ohos.ability.featureAbility'
|
||||
import ArkWorker from '@ohos.worker'
|
||||
|
||||
export class Pngj {
|
||||
|
@ -60,17 +59,16 @@ export class Pngj {
|
|||
callback(pngBuffer, newPng);
|
||||
}
|
||||
|
||||
readPngImageAsync(worker:ArkWorker.Worker, pngBuffer: ArrayBuffer, callback:PngCallback<ArrayBuffer, any>){
|
||||
|
||||
worker.onerror = function(data){
|
||||
readPngImageAsync(worker: any, pngBuffer: ArrayBuffer, callback: PngCallback<ArrayBuffer, any>) {
|
||||
worker.onerror = function (data) {
|
||||
|
||||
}
|
||||
|
||||
worker.onmessageerror = function(e){
|
||||
worker.onmessageerror = function (e) {
|
||||
|
||||
}
|
||||
|
||||
worker.onexit = function(){
|
||||
worker.onexit = function () {
|
||||
|
||||
}
|
||||
|
||||
|
@ -85,24 +83,20 @@ export class Pngj {
|
|||
}
|
||||
worker.terminate();
|
||||
}
|
||||
|
||||
var obj = { type: 'readPngImageAsync', data:pngBuffer}
|
||||
var obj = { type: 'readPngImageAsync', data: pngBuffer }
|
||||
worker.postMessage(obj, [pngBuffer])
|
||||
|
||||
}
|
||||
|
||||
|
||||
writePngWithStringAsync(worker:ArkWorker.Worker,addInfo:string, pngBuffer:ArrayBuffer, callback:PngCallback<ArrayBuffer,any>) {
|
||||
|
||||
worker.onerror = function(data){
|
||||
writePngWithStringAsync(worker: any, addInfo: string, pngBuffer: ArrayBuffer, callback: PngCallback<ArrayBuffer, any>) {
|
||||
worker.onerror = function (data) {
|
||||
|
||||
}
|
||||
|
||||
worker.onmessageerror = function(e){
|
||||
worker.onmessageerror = function (e) {
|
||||
|
||||
}
|
||||
|
||||
worker.onexit = function(){
|
||||
worker.onexit = function () {
|
||||
|
||||
}
|
||||
|
||||
|
@ -123,18 +117,16 @@ export class Pngj {
|
|||
|
||||
}
|
||||
|
||||
|
||||
writePngAsync(worker:ArkWorker.Worker,pngBuffer:ArrayBuffer, callback:PngCallback<ArrayBuffer,any>) {
|
||||
|
||||
worker.onerror = function(data){
|
||||
writePngAsync(worker: any, pngBuffer: ArrayBuffer, callback: PngCallback<ArrayBuffer, any>) {
|
||||
worker.onerror = function (data) {
|
||||
|
||||
}
|
||||
|
||||
worker.onmessageerror = function(e){
|
||||
worker.onmessageerror = function (e) {
|
||||
|
||||
}
|
||||
|
||||
worker.onexit = function(){
|
||||
worker.onexit = function () {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
/* crc32.js (C) 2014-present SheetJS -- http://sheetjs.com */
|
||||
/* vim: set ts=2: */
|
||||
/*exported CRC32 */
|
||||
export var Crc32;
|
||||
(function(factory){
|
||||
/*jshint ignore:start */
|
||||
/*eslint-disable */
|
||||
|
||||
factory(Crc32 = {});
|
||||
|
||||
/*eslint-enable */
|
||||
/*jshint ignore:end */
|
||||
}(function (CRC32) {
|
||||
CRC32.version = '1.2.0';
|
||||
/* see perf/crc32table.js */
|
||||
/*global Int32Array */
|
||||
function signed_crc_table() {
|
||||
var c = 0, table = new Array(256);
|
||||
|
||||
for (var n = 0; n != 256; ++n) {
|
||||
c = n;
|
||||
c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
|
||||
c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
|
||||
c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
|
||||
c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
|
||||
c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
|
||||
c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
|
||||
c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
|
||||
c = ((c & 1) ? (-306674912 ^ (c >>> 1)) : (c >>> 1));
|
||||
table[n] = c;
|
||||
}
|
||||
|
||||
return typeof Int32Array !== 'undefined' ? new Int32Array(table) : table;
|
||||
}
|
||||
|
||||
var T = signed_crc_table();
|
||||
|
||||
function crc32_bstr(bstr, seed) {
|
||||
var C = seed ^ -1, L = bstr.length - 1;
|
||||
for (var i = 0; i < L; ) {
|
||||
C = (C >>> 8) ^ T[(C ^ bstr.charCodeAt(i++))&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ bstr.charCodeAt(i++))&0xFF];
|
||||
}
|
||||
if (i === L) C = (C >>> 8) ^ T[(C ^ bstr.charCodeAt(i))&0xFF];
|
||||
return C ^ -1;
|
||||
}
|
||||
|
||||
function crc32_buf(buf, seed) {
|
||||
if (buf.length > 10000) return crc32_buf_8(buf, seed);
|
||||
var C = seed ^ -1, L = buf.length - 3;
|
||||
for (var i = 0; i < L; ) {
|
||||
C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
}
|
||||
while (i < L + 3) C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
return C ^ -1;
|
||||
}
|
||||
|
||||
function crc32_buf_8(buf, seed) {
|
||||
var C = seed ^ -1, L = buf.length - 7;
|
||||
for (var i = 0; i < L; ) {
|
||||
C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
}
|
||||
while (i < L + 7) C = (C >>> 8) ^ T[(C ^ buf[i++])&0xFF];
|
||||
return C ^ -1;
|
||||
}
|
||||
|
||||
function crc32_str(str, seed) {
|
||||
var C = seed ^ -1;
|
||||
for (var i = 0, L = str.length, c, d; i < L; ) {
|
||||
c = str.charCodeAt(i++);
|
||||
if (c < 0x80) {
|
||||
C = (C >>> 8) ^ T[(C ^ c)&0xFF];
|
||||
} else if (c < 0x800) {
|
||||
C = (C >>> 8) ^ T[(C ^ (192 | ((c >> 6) & 31)))&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ (128 | (c & 63)))&0xFF];
|
||||
} else if (c >= 0xD800 && c < 0xE000) {
|
||||
c = (c & 1023) + 64;
|
||||
d = str.charCodeAt(i++) & 1023;
|
||||
C = (C >>> 8) ^ T[(C ^ (240 | ((c >> 8) & 7)))&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ (128 | ((c >> 2) & 63)))&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ (128 | ((d >> 6) & 15) | ((c & 3) << 4)))&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ (128 | (d & 63)))&0xFF];
|
||||
} else {
|
||||
C = (C >>> 8) ^ T[(C ^ (224 | ((c >> 12) & 15)))&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ (128 | ((c >> 6) & 63)))&0xFF];
|
||||
C = (C >>> 8) ^ T[(C ^ (128 | (c & 63)))&0xFF];
|
||||
}
|
||||
}
|
||||
return C ^ -1;
|
||||
}
|
||||
|
||||
CRC32.table = T;
|
||||
// $FlowIgnore
|
||||
CRC32.bstr = crc32_bstr;
|
||||
// $FlowIgnore
|
||||
CRC32.buf = crc32_buf;
|
||||
// $FlowIgnore
|
||||
CRC32.str = crc32_str;
|
||||
}));
|
|
@ -0,0 +1,423 @@
|
|||
/**
|
||||
* library to read and write PNG Metadata
|
||||
*
|
||||
* References:
|
||||
* w3 PNG Chunks specification: https://www.w3.org/TR/PNG-Chunks.html
|
||||
* The Metadata in PNG files: https://dev.exiv2.org/projects/exiv2/wiki/The_Metadata_in_PNG_files
|
||||
*/
|
||||
|
||||
import { Crc32 } from './crc32'
|
||||
|
||||
|
||||
// Used for fast-ish conversion between uint8s and uint32s/int32s.
|
||||
// Also required in order to remain agnostic for both Node Buffers and
|
||||
// Uint8Arrays.
|
||||
let uint8 = new Uint8Array(4)
|
||||
let int32 = new Int32Array(uint8.buffer)
|
||||
let uint32 = new Uint32Array(uint8.buffer)
|
||||
|
||||
export const RESOLUTION_UNITS = { UNDEFINED: 0, METERS: 1, INCHES: 2 };
|
||||
|
||||
/**
|
||||
* https://github.com/aheckmann/sliced
|
||||
* An Array.prototype.slice.call(arguments) alternative
|
||||
* @param {Object} args something with a length
|
||||
* @param {Number} slice
|
||||
* @param {Number} sliceEnd
|
||||
* @api public
|
||||
*/
|
||||
function sliced(args, slice, sliceEnd) {
|
||||
var ret = [];
|
||||
var len = args.length;
|
||||
|
||||
if (0 === len) return ret;
|
||||
|
||||
var start = slice < 0
|
||||
? Math.max(0, slice + len)
|
||||
: slice || 0;
|
||||
|
||||
if (sliceEnd !== undefined) {
|
||||
len = sliceEnd < 0
|
||||
? sliceEnd + len
|
||||
: sliceEnd
|
||||
}
|
||||
|
||||
while (len-- > start) {
|
||||
ret[len - start] = args[len];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* https://github.com/hughsk/png-chunk-text
|
||||
* Returns a chunk object containing the metadata for a given key and value:
|
||||
* @param keyword
|
||||
* @param content
|
||||
* @param chunkName
|
||||
* @returns {{data: Uint8Array, name: 'tEXt'}}
|
||||
*/
|
||||
export function textEncode(keyword, content, chunkName = 'tEXt') {
|
||||
keyword = String(keyword)
|
||||
content = String(content)
|
||||
|
||||
if (content.length && (!/^[\x00-\xFF]+$/.test(keyword) || !/^[\x00-\xFF]+$/.test(content))) {
|
||||
throw new Error('Only Latin-1 characters are permitted in PNG tEXt chunks. You might want to consider base64 encoding and/or zEXt compression')
|
||||
}
|
||||
|
||||
if (keyword.length >= 80) {
|
||||
throw new Error('Keyword "' + keyword + '" is longer than the 79-character limit imposed by the PNG specification')
|
||||
}
|
||||
|
||||
let totalSize = keyword.length + content.length + 1
|
||||
let output = new Uint8Array(totalSize)
|
||||
let idx = 0
|
||||
let code
|
||||
|
||||
for (let i = 0; i < keyword.length; i++) {
|
||||
if (!(code = keyword.charCodeAt(i))) {
|
||||
throw new Error('0x00 character is not permitted in tEXt keywords')
|
||||
}
|
||||
|
||||
output[idx++] = code
|
||||
}
|
||||
|
||||
output[idx++] = 0
|
||||
|
||||
for (let j = 0; j < content.length; j++) {
|
||||
if (!(code = content.charCodeAt(j))) {
|
||||
throw new Error('0x00 character is not permitted in tEXt content')
|
||||
}
|
||||
|
||||
output[idx++] = code
|
||||
}
|
||||
|
||||
return {
|
||||
name: chunkName,
|
||||
data: output
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* https://github.com/hughsk/png-chunk-text
|
||||
* Reads a Uint8Array or Node.js Buffer instance containing a tEXt PNG chunk's data and returns its keyword/text:
|
||||
* @param data
|
||||
* @returns {{text: string, keyword: string}}
|
||||
*/
|
||||
export function textDecode(data) {
|
||||
if (data.data && data.name) {
|
||||
data = data.data
|
||||
}
|
||||
|
||||
let naming = true
|
||||
let text = ''
|
||||
let name = ''
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
let code = data[i]
|
||||
|
||||
if (naming) {
|
||||
if (code) {
|
||||
name += String.fromCharCode(code)
|
||||
} else {
|
||||
naming = false
|
||||
}
|
||||
} else {
|
||||
if (code) {
|
||||
text += String.fromCharCode(code)
|
||||
} else {
|
||||
throw new Error('Invalid NULL character found. 0x00 character is not permitted in tEXt content')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
keyword: name,
|
||||
text: text
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* https://github.com/hughsk/png-chunks-extract
|
||||
* Extract the data chunks from a PNG file.
|
||||
* Useful for reading the metadata of a PNG image, or as the base of a more complete PNG parser.
|
||||
* Takes the raw image file data as a Uint8Array or Node.js Buffer, and returns an array of chunks. Each chunk has a name and data buffer:
|
||||
* @param data {Uint8Array}
|
||||
* @returns {[{name: String, data: Uint8Array}]}
|
||||
*/
|
||||
export function extractChunks(data) {
|
||||
if (data[0] !== 0x89) throw new Error('Invalid .png file header')
|
||||
if (data[1] !== 0x50) throw new Error('Invalid .png file header')
|
||||
if (data[2] !== 0x4E) throw new Error('Invalid .png file header')
|
||||
if (data[3] !== 0x47) throw new Error('Invalid .png file header')
|
||||
if (data[4] !== 0x0D) throw new Error('Invalid .png file header: possibly caused by DOS-Unix line ending conversion?')
|
||||
if (data[5] !== 0x0A) throw new Error('Invalid .png file header: possibly caused by DOS-Unix line ending conversion?')
|
||||
if (data[6] !== 0x1A) throw new Error('Invalid .png file header')
|
||||
if (data[7] !== 0x0A) throw new Error('Invalid .png file header: possibly caused by DOS-Unix line ending conversion?')
|
||||
|
||||
let ended = false
|
||||
let chunks = []
|
||||
let idx = 8
|
||||
|
||||
while (idx < data.length) {
|
||||
// Read the length of the current chunk,
|
||||
// which is stored as a Uint32.
|
||||
uint8[3] = data[idx++]
|
||||
uint8[2] = data[idx++]
|
||||
uint8[1] = data[idx++]
|
||||
uint8[0] = data[idx++]
|
||||
|
||||
// Chunk includes name/type for CRC check (see below).
|
||||
let length = uint32[0] + 4
|
||||
let chunk = new Uint8Array(length)
|
||||
chunk[0] = data[idx++]
|
||||
chunk[1] = data[idx++]
|
||||
chunk[2] = data[idx++]
|
||||
chunk[3] = data[idx++]
|
||||
|
||||
// Get the name in ASCII for identification.
|
||||
let name = (
|
||||
String.fromCharCode(chunk[0]) +
|
||||
String.fromCharCode(chunk[1]) +
|
||||
String.fromCharCode(chunk[2]) +
|
||||
String.fromCharCode(chunk[3])
|
||||
)
|
||||
|
||||
// The IHDR header MUST come first.
|
||||
if (!chunks.length && name !== 'IHDR') {
|
||||
throw new Error('IHDR header missing')
|
||||
}
|
||||
|
||||
// The IEND header marks the end of the file,
|
||||
// so on discovering it break out of the loop.
|
||||
if (name === 'IEND') {
|
||||
ended = true
|
||||
chunks.push({
|
||||
name: name,
|
||||
data: new Uint8Array(0)
|
||||
})
|
||||
|
||||
break
|
||||
}
|
||||
|
||||
// Read the contents of the chunk out of the main buffer.
|
||||
for (let i = 4; i < length; i++) {
|
||||
chunk[i] = data[idx++]
|
||||
}
|
||||
|
||||
// Read out the CRC value for comparison.
|
||||
// It's stored as an Int32.
|
||||
uint8[3] = data[idx++]
|
||||
uint8[2] = data[idx++]
|
||||
uint8[1] = data[idx++]
|
||||
uint8[0] = data[idx++]
|
||||
|
||||
let crcActual = int32[0]
|
||||
let crcExpect = Crc32.buf(chunk)
|
||||
if (crcExpect !== crcActual) {
|
||||
throw new Error(
|
||||
'CRC values for ' + name + ' header do not match, PNG file is likely corrupted'
|
||||
)
|
||||
}
|
||||
|
||||
// The chunk data is now copied to remove the 4 preceding
|
||||
// bytes used for the chunk name/type.
|
||||
let chunkData = new Uint8Array(chunk.buffer.slice(4))
|
||||
|
||||
chunks.push({
|
||||
name: name,
|
||||
data: chunkData
|
||||
})
|
||||
}
|
||||
|
||||
if (!ended) {
|
||||
throw new Error('.png file ended prematurely: no IEND header was found')
|
||||
}
|
||||
|
||||
return chunks
|
||||
}
|
||||
|
||||
/**
|
||||
* https://github.com/hughsk/png-chunks-encode
|
||||
* Return a fresh PNG buffer given a set of PNG chunks. Useful in combination with png-chunks-encode to easily modify or add to the data of a PNG file.
|
||||
* Takes an array of chunks, each with a name and data:
|
||||
* @param chunks {[{name: String, data: Uint8Array}]}
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function encodeChunks(chunks) {
|
||||
let totalSize = 8
|
||||
let idx = totalSize
|
||||
let i
|
||||
|
||||
for (i = 0; i < chunks.length; i++) {
|
||||
totalSize += chunks[i].data.length
|
||||
totalSize += 12
|
||||
}
|
||||
|
||||
let output = new Uint8Array(totalSize)
|
||||
|
||||
output[0] = 0x89
|
||||
output[1] = 0x50
|
||||
output[2] = 0x4E
|
||||
output[3] = 0x47
|
||||
output[4] = 0x0D
|
||||
output[5] = 0x0A
|
||||
output[6] = 0x1A
|
||||
output[7] = 0x0A
|
||||
|
||||
for (i = 0; i < chunks.length; i++) {
|
||||
let chunk = chunks[i]
|
||||
let name = chunk.name
|
||||
let data = chunk.data
|
||||
let size = data.length
|
||||
let nameChars = [
|
||||
name.charCodeAt(0),
|
||||
name.charCodeAt(1),
|
||||
name.charCodeAt(2),
|
||||
name.charCodeAt(3)
|
||||
]
|
||||
|
||||
uint32[0] = size
|
||||
output[idx++] = uint8[3]
|
||||
output[idx++] = uint8[2]
|
||||
output[idx++] = uint8[1]
|
||||
output[idx++] = uint8[0]
|
||||
|
||||
output[idx++] = nameChars[0]
|
||||
output[idx++] = nameChars[1]
|
||||
output[idx++] = nameChars[2]
|
||||
output[idx++] = nameChars[3]
|
||||
|
||||
for (let j = 0; j < size; ) {
|
||||
output[idx++] = data[j++]
|
||||
}
|
||||
|
||||
let crcCheck = nameChars.concat(sliced(data, undefined, undefined));
|
||||
int32[0] = Crc32.buf(crcCheck)
|
||||
output[idx++] = uint8[3]
|
||||
output[idx++] = uint8[2]
|
||||
output[idx++] = uint8[1]
|
||||
output[idx++] = uint8[0]
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
/**
|
||||
* read 4 bytes number from UInt8Array.
|
||||
* @param uint8array
|
||||
* @param offset
|
||||
* @returns {number}
|
||||
*/
|
||||
function readUint32(uint8array, offset) {
|
||||
let byte1, byte2, byte3, byte4;
|
||||
byte1 = uint8array[offset++];
|
||||
byte2 = uint8array[offset++];
|
||||
byte3 = uint8array[offset++];
|
||||
byte4 = uint8array[offset];
|
||||
return 0 | (byte1 << 24) | (byte2 << 16) | (byte3 << 8) | byte4;
|
||||
}
|
||||
|
||||
/**
|
||||
* write 4 bytes number to UInt8Array.
|
||||
* @param uint8array
|
||||
* @param num
|
||||
* @param offset
|
||||
*/
|
||||
function writeUInt32(uint8array, num, offset) {
|
||||
uint8array[offset] = (num & 0xff000000) >> 24;
|
||||
uint8array[offset + 1] = (num & 0x00ff0000) >> 16;
|
||||
uint8array[offset + 2] = (num & 0x0000ff00) >> 8;
|
||||
uint8array[offset + 3] = (num & 0x000000ff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get object with PNG metadata. only tEXt and pHYs chunks are parsed
|
||||
* @param buffer {Buffer}
|
||||
* @returns {{tEXt: {keyword: value}, pHYs: {x: number, y: number, units: RESOLUTION_UNITS}, [string]: true}}
|
||||
*/
|
||||
export function readMetadata(buffer) {
|
||||
let result = {};
|
||||
const chunks = extractChunks(buffer);
|
||||
chunks.forEach(chunk => {
|
||||
switch (chunk.name) {
|
||||
case 'tEXt':
|
||||
if (!result['tEXt']) {
|
||||
result['tEXt'] = {};
|
||||
}
|
||||
let textChunk = textDecode(chunk.data);
|
||||
result['tEXt'][textChunk.keyword] = textChunk.text;
|
||||
break
|
||||
case 'pHYs':
|
||||
result['pHYs'] = {
|
||||
// Pixels per unit, X axis: 4 bytes (unsigned integer)
|
||||
"x": readUint32(chunk.data, 0),
|
||||
// Pixels per unit, Y axis: 4 bytes (unsigned integer)
|
||||
"y": readUint32(chunk.data, 4),
|
||||
"unit": chunk.data[8],
|
||||
}
|
||||
break
|
||||
case 'gAMA':
|
||||
case 'cHRM':
|
||||
case 'sRGB':
|
||||
case 'IHDR':
|
||||
case 'iCCP':
|
||||
default:
|
||||
result[chunk.name] = true;
|
||||
}
|
||||
})
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* create new Buffer with metadata. only tEXt and pHYs chunks are supported.
|
||||
* @param buffer {Buffer}
|
||||
* @param metadata {{tEXt: {keyword: value}, pHYs: {x: number, y: number, units: RESOLUTION_UNITS}}}
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
export function writeMetadata(buffer, metadata) {
|
||||
const chunks = extractChunks(buffer);
|
||||
insertMetadata(chunks, metadata);
|
||||
ArrayBuffer
|
||||
let out = encodeChunks(chunks).buffer;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
export function insertMetadata(chunks, metadata) {
|
||||
if (metadata.clear) {
|
||||
for (let i = chunks.length - 1; i--; ) {
|
||||
switch (chunks[i].name) {
|
||||
case 'IHDR':
|
||||
case 'IDAT':
|
||||
case 'IEND':
|
||||
break;
|
||||
default:
|
||||
chunks.splice(i, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (metadata.tEXt) {
|
||||
for (var keyword in metadata.tEXt) {
|
||||
chunks.splice(-1, 0, textEncode(keyword, metadata.tEXt[keyword]))
|
||||
}
|
||||
}
|
||||
|
||||
if (metadata.pHYs) {
|
||||
const data = new Uint8Array(9);
|
||||
writeUInt32(data, metadata.pHYs.x, 0)
|
||||
writeUInt32(data, metadata.pHYs.y, 4)
|
||||
data[8] = metadata.pHYs.units; // inches
|
||||
|
||||
let pHYs = chunks.find(chunk => chunk.name === "pHYs");
|
||||
if (pHYs) {
|
||||
pHYs.data = data;
|
||||
}
|
||||
else {
|
||||
chunks.splice(1, 0, { name: "pHYs", data: data })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -13,8 +13,8 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {ICache} from "../requestmanage/ICache"
|
||||
import {DiskLruCache} from "../../cache/DiskLruCache"
|
||||
import { ICache } from "../requestmanage/ICache"
|
||||
import { DiskLruCache } from "@ohos/disklrucache"
|
||||
|
||||
export class DiskCacheProxy implements ICache<string, ArrayBuffer> {
|
||||
private mDiskLruCache: DiskLruCache;
|
||||
|
@ -29,7 +29,7 @@ export class DiskCacheProxy implements ICache<string, ArrayBuffer> {
|
|||
}
|
||||
|
||||
getCachePath():string{
|
||||
let folderPath = this.mDiskLruCache.dirPath
|
||||
let folderPath = this.mDiskLruCache.getPath();
|
||||
if (folderPath.endsWith('/')) {
|
||||
return folderPath;
|
||||
} else {
|
||||
|
@ -38,11 +38,11 @@ export class DiskCacheProxy implements ICache<string, ArrayBuffer> {
|
|||
}
|
||||
|
||||
getValue(key: string): ArrayBuffer{
|
||||
return this.mDiskLruCache.getCacheDataByKey(key);
|
||||
return this.mDiskLruCache.get(key);
|
||||
}
|
||||
|
||||
putValue(key: string, value: ArrayBuffer) {
|
||||
this.mDiskLruCache.putCacheData(key, value, null)
|
||||
async putValue(key: string, value: ArrayBuffer) {
|
||||
await this.mDiskLruCache.setAsync(key, value)
|
||||
}
|
||||
|
||||
removeValue(key: string): ArrayBuffer{
|
||||
|
|
|
@ -29,7 +29,6 @@ export class MemoryCacheProxy <K, V> implements ICache<K, V> {
|
|||
}
|
||||
|
||||
getValue(key: K): V{
|
||||
console.log("Level1MemoryCache getValue come in!");
|
||||
return this.mLruCache.get(key);
|
||||
}
|
||||
|
||||
|
|
|
@ -13,9 +13,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {RequestOption} from "../../imageknife/RequestOption"
|
||||
import {DiskLruCache} from "../../cache/DiskLruCache"
|
||||
import {LruCache} from "../../cache/LruCache"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import { DiskLruCache } from "@ohos/disklrucache"
|
||||
import { LruCache } from "../../cache/LruCache"
|
||||
import {FileUtils} from "../../cache/FileUtils"
|
||||
import {Md5} from "../../cache/Md5"
|
||||
import{MemoryCacheProxy} from "../requestmanage/MemoryCacheProxy"
|
||||
|
@ -485,8 +485,8 @@ export class RequestManager {
|
|||
new Promise((resolve, reject) => {
|
||||
resolve(source)
|
||||
})
|
||||
.then((arraybuffer: ArrayBuffer) => {
|
||||
this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
|
||||
.then(async (arraybuffer: ArrayBuffer) => {
|
||||
await this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("save diskLruCache error=" + err);
|
||||
|
@ -541,18 +541,18 @@ export class RequestManager {
|
|||
return imageKnifeData;
|
||||
}
|
||||
|
||||
private saveCacheAndDisk(value: PixelMap, filetype:string, onComplete, source:ArrayBuffer){
|
||||
private saveCacheAndDisk(value: PixelMap, filetype:string, onComplete, source:ArrayBuffer) {
|
||||
let imageKnifeData = this.createImageKnifeData(ImageKnifeData.PIXELMAP, value, filetype);
|
||||
this.mMemoryCacheProxy.putValue(this.options.generateCacheKey, imageKnifeData);
|
||||
let save2DiskCache = (arraybuffer) => {
|
||||
this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
|
||||
}
|
||||
let save2DiskCache = async (arraybuffer) => {
|
||||
await this.mDiskCacheProxy.putValue(this.options.generateDataKey, arraybuffer)
|
||||
}
|
||||
let runSave2Disk = (resolve, reject) => {
|
||||
resolve(source);
|
||||
}
|
||||
}
|
||||
let promise = new Promise(runSave2Disk);
|
||||
promise.then(save2DiskCache);
|
||||
onComplete(imageKnifeData);
|
||||
promise.then(save2DiskCache);
|
||||
onComplete(imageKnifeData);
|
||||
}
|
||||
|
||||
thumbnailProcess(source:ArrayBuffer, filetype:string, onComplete, onError){
|
||||
|
|
|
@ -23,16 +23,14 @@ export class ParseResClient implements IResourceFetch {
|
|||
let resId = res.id;
|
||||
let resType = res.type;
|
||||
if (resType == ResourceTypeEts.MEDIA) {
|
||||
resourceManager.getResourceManager()
|
||||
.then(result => {
|
||||
result.getMedia(resId)
|
||||
.then(data => {
|
||||
let arrayBuffer = this.typedArrayToBuffer(data);
|
||||
onCompleteFunction(arrayBuffer)
|
||||
})
|
||||
.catch(err => {
|
||||
onErrorFunction(err)
|
||||
})
|
||||
globalThis.ImageKnife.getImageKnifeContext().resourceManager
|
||||
.getMedia(resId)
|
||||
.then(data => {
|
||||
let arrayBuffer = this.typedArrayToBuffer(data);
|
||||
onCompleteFunction(arrayBuffer)
|
||||
})
|
||||
.catch(err => {
|
||||
onErrorFunction(err)
|
||||
})
|
||||
}
|
||||
else if (resType == ResourceTypeEts.RAWFILE) {
|
||||
|
|
|
@ -24,21 +24,19 @@ export class ParseResClientBase64 implements IResourceFetch {
|
|||
let resId = res.id;
|
||||
let resType = res.type;
|
||||
if (resType == ResourceTypeEts.MEDIA) {
|
||||
resourceManager.getResourceManager()
|
||||
.then(result => {
|
||||
result.getMediaBase64(resId)
|
||||
.then(data => {
|
||||
let matchReg = ';base64,';
|
||||
var firstIndex = data.indexOf(matchReg)
|
||||
data = data.substring(firstIndex + matchReg.length, data.length)
|
||||
let arrayBuffer = Base64.getInstance()
|
||||
.decode(data);
|
||||
onCompleteFunction(arrayBuffer)
|
||||
})
|
||||
.catch(err => {
|
||||
onErrorFunction(err)
|
||||
})
|
||||
globalThis.ImageKnife.getImageKnifeContext().resourceManager
|
||||
.getMediaBase64(resId)
|
||||
.then(data => {
|
||||
let matchReg = ';base64,';
|
||||
var firstIndex = data.indexOf(matchReg)
|
||||
data = data.substring(firstIndex + matchReg.length, data.length)
|
||||
let arrayBuffer = Base64.getInstance()
|
||||
.decode(data);
|
||||
onCompleteFunction(arrayBuffer)
|
||||
})
|
||||
.catch(err => {
|
||||
onErrorFunction(err)
|
||||
})
|
||||
}
|
||||
else if (resType == ResourceTypeEts.RAWFILE) {
|
||||
onErrorFunction('ParseResClientBase64 本地资源是rawfile暂时无法解析出错')
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import { TransformUtils } from "../transform/TransformUtils"
|
||||
import image from "@ohos.multimedia.image"
|
||||
import {fastBlur} from "../utils/FastBlur"
|
||||
import { fastBlur } from "../utils/FastBlur"
|
||||
|
||||
|
||||
export class BlurTransformation implements BaseTransform<PixelMap> {
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import image from "@ohos.multimedia.image"
|
||||
|
||||
|
||||
|
@ -24,7 +24,7 @@ import image from "@ohos.multimedia.image"
|
|||
* brightness value ranges from -1.0 to 1.0, with 0.0 as the normal level
|
||||
*/
|
||||
export class BrightnessFilterTransformation implements BaseTransform<PixelMap> {
|
||||
private _mBrightness: number= 0.0;
|
||||
private _mBrightness: number = 0.0;
|
||||
|
||||
constructor(brightness: number) {
|
||||
this._mBrightness = brightness;
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import image from "@ohos.multimedia.image"
|
||||
|
||||
|
||||
|
|
|
@ -13,18 +13,18 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import { TransformUtils } from "../transform/TransformUtils"
|
||||
import image from "@ohos.multimedia.image"
|
||||
|
||||
export class CropCircleTransformation implements BaseTransform<PixelMap> {
|
||||
private static TAG: string= "CropCircleTransformation";
|
||||
private mCenterX: number= 0;
|
||||
private mCenterY: number= 0;
|
||||
private mRadius: number= 0;
|
||||
private static TAG: string = "CropCircleTransformation";
|
||||
private mCenterX: number = 0;
|
||||
private mCenterY: number = 0;
|
||||
private mRadius: number = 0;
|
||||
|
||||
getName() {
|
||||
return CropCircleTransformation.TAG + ";mCenterX:" + this.mCenterX
|
||||
|
|
|
@ -13,21 +13,21 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import { TransformUtils } from "../transform/TransformUtils"
|
||||
import image from "@ohos.multimedia.image"
|
||||
|
||||
export class CropCircleWithBorderTransformation implements BaseTransform<PixelMap> {
|
||||
private static TAG: string= "CropCircleTransformation";
|
||||
private mBorderSize: number= 5;
|
||||
private mCenterX: number= 0;
|
||||
private mCenterY: number= 0;
|
||||
private mRadius: number= 0;
|
||||
private mRColor: number= 0;
|
||||
private mGColor: number= 0;
|
||||
private static TAG: string = "CropCircleTransformation";
|
||||
private mBorderSize: number = 5;
|
||||
private mCenterX: number = 0;
|
||||
private mCenterY: number = 0;
|
||||
private mRadius: number = 0;
|
||||
private mRColor: number = 0;
|
||||
private mGColor: number = 0;
|
||||
private mBColor: number= 0;
|
||||
|
||||
constructor(border_size: number, value: {
|
||||
|
|
|
@ -13,15 +13,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
|
||||
import image from "@ohos.multimedia.image"
|
||||
|
||||
export class CropSquareTransformation implements BaseTransform<PixelMap> {
|
||||
private static TAG: string= "CropSquareTransformation";
|
||||
private static TAG: string = "CropSquareTransformation";
|
||||
|
||||
getName() {
|
||||
return CropSquareTransformation.TAG + ";CropSquareTransformation:" + this;
|
||||
|
|
|
@ -13,18 +13,18 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import { TransformUtils } from "../transform/TransformUtils"
|
||||
import image from "@ohos.multimedia.image"
|
||||
|
||||
export class CropTransformation implements BaseTransform<PixelMap> {
|
||||
private static TAG: string= "CropCircleTransformation";
|
||||
private static TAG: string = "CropCircleTransformation";
|
||||
private mWidth: number;
|
||||
private mHeight: number;
|
||||
private mCropType: CropType= CropType.CENTER;
|
||||
private mCropType: CropType = CropType.CENTER;
|
||||
|
||||
constructor(width: number, height: number, cropType?: CropType) {
|
||||
this.mWidth = width;
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import { TransformUtils } from "../transform/TransformUtils"
|
||||
import image from "@ohos.multimedia.image"
|
||||
|
||||
export class GrayscaleTransformation implements BaseTransform<PixelMap> {
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import image from "@ohos.multimedia.image"
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,11 +13,11 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import {MaskUtils} from "../utils/MaskUtils.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import { MaskUtils } from "../utils/MaskUtils"
|
||||
import image from "@ohos.multimedia.image"
|
||||
import resmgr from "@ohos.resourceManager"
|
||||
|
||||
|
|
|
@ -13,20 +13,20 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import { TransformUtils } from "../transform/TransformUtils"
|
||||
import image from "@ohos.multimedia.image"
|
||||
import {pixelUtils} from "../utils/PixelUtils"
|
||||
import { pixelUtils } from "../utils/PixelUtils"
|
||||
|
||||
/**
|
||||
* Applies a Pixelation effect to the image.
|
||||
* The pixel with a default of 10.0.
|
||||
*/
|
||||
export class PixelationFilterTransformation implements BaseTransform<PixelMap> {
|
||||
private _mPixel: number= 10.0;
|
||||
private _mPixel: number = 10.0;
|
||||
|
||||
constructor(pixel?: number) {
|
||||
if (pixel) {
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import { TransformUtils } from "../transform/TransformUtils"
|
||||
|
||||
import image from "@ohos.multimedia.image"
|
||||
|
||||
|
|
|
@ -12,20 +12,20 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {ArcPoint} from "../entry/ArcPoint.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import {TransformUtils} from "../transform/TransformUtils.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { ArcPoint } from "../entry/ArcPoint"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import { TransformUtils } from "../transform/TransformUtils"
|
||||
|
||||
import image from "@ohos.multimedia.image"
|
||||
|
||||
export class RoundedCornersTransformation implements BaseTransform<PixelMap> {
|
||||
private mTop_left: number= 0;
|
||||
private mTop_right: number= 0;
|
||||
private mBottom_left: number= 0;
|
||||
private mBottom_right: number= 0;
|
||||
private mTop_left: number = 0;
|
||||
private mTop_right: number = 0;
|
||||
private mBottom_left: number = 0;
|
||||
private mBottom_right: number = 0;
|
||||
private mTransform_pixelMap: any;
|
||||
private mPoint: ArcPoint[];
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from "../transform/BaseTransform.ets"
|
||||
import {AsyncTransform} from "../transform/AsyncTransform.ets"
|
||||
import {Constants} from "../constants/Constants.ets"
|
||||
import {RequestOption} from "../../imageknife/RequestOption.ets"
|
||||
import { BaseTransform } from "../transform/BaseTransform"
|
||||
import { AsyncTransform } from "../transform/AsyncTransform"
|
||||
import { Constants } from "../constants/Constants"
|
||||
import { RequestOption } from "../../imageknife/RequestOption"
|
||||
import image from "@ohos.multimedia.image"
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,13 +13,13 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from '../transform/BaseTransform.ets'
|
||||
import {AsyncTransform} from '../transform/AsyncTransform.ets'
|
||||
import {Constants} from '../constants/Constants.ets'
|
||||
import {RequestOption} from '../../imageknife/RequestOption.ets'
|
||||
import {TransformUtils} from '../transform/TransformUtils.ets'
|
||||
import { BaseTransform } from '../transform/BaseTransform'
|
||||
import { AsyncTransform } from '../transform/AsyncTransform'
|
||||
import { Constants } from '../constants/Constants'
|
||||
import { RequestOption } from '../../imageknife/RequestOption'
|
||||
import { TransformUtils } from '../transform/TransformUtils'
|
||||
import image from '@ohos.multimedia.image'
|
||||
import {CalculatePixelUtils} from '../utils/CalculatePixelUtils'
|
||||
import { CalculatePixelUtils } from '../utils/CalculatePixelUtils'
|
||||
|
||||
export class SketchFilterTransformation implements BaseTransform<PixelMap> {
|
||||
getName() {
|
||||
|
|
|
@ -13,15 +13,15 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {BaseTransform} from '../transform/BaseTransform.ets'
|
||||
import {AsyncTransform} from '../transform/AsyncTransform.ets'
|
||||
import {Constants} from '../constants/Constants.ets'
|
||||
import {RequestOption} from '../../imageknife/RequestOption.ets'
|
||||
import {TransformUtils} from '../transform/TransformUtils.ets'
|
||||
import { BaseTransform } from '../transform/BaseTransform'
|
||||
import { AsyncTransform } from '../transform/AsyncTransform'
|
||||
import { Constants } from '../constants/Constants'
|
||||
import { RequestOption } from '../../imageknife/RequestOption'
|
||||
import { TransformUtils } from '../transform/TransformUtils'
|
||||
import image from '@ohos.multimedia.image'
|
||||
import {PixelEntry} from '../entry/PixelEntry'
|
||||
import {ColorUtils} from '../utils/ColorUtils'
|
||||
import {CalculatePixelUtils} from '../utils/CalculatePixelUtils'
|
||||
import { PixelEntry } from '../entry/PixelEntry'
|
||||
import { ColorUtils } from '../utils/ColorUtils'
|
||||
import { CalculatePixelUtils } from '../utils/CalculatePixelUtils'
|
||||
|
||||
export class SwirlFilterTransformation implements BaseTransform<PixelMap> {
|
||||
private _degree: number;
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import resmgr from '@ohos.resourceManager'
|
||||
import {DataCallBack} from "../interface/DataCallBack"
|
||||
|
||||
export namespace ColorUtils {
|
||||
|
@ -22,22 +21,19 @@ export namespace ColorUtils {
|
|||
* ColorUtils.parseColor("color_name",callback)
|
||||
*/
|
||||
export function parseColor(c: string, callback: DataCallBack<string>) {
|
||||
resmgr.getResourceManager()
|
||||
.then(result => {
|
||||
|
||||
var reColor = 'sys.color.' + c;
|
||||
result.getString($r(reColor)
|
||||
.id, (err, color) => {
|
||||
if (!err) {
|
||||
var cos = JSON.stringify(color);
|
||||
callback.callback(cos)
|
||||
} else {
|
||||
callback.callback(err.message)
|
||||
}
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
callback.callback(error.message)
|
||||
})
|
||||
globalThis.ImageKnife.getImageKnifeContext().resourceManager.getString($r(reColor)
|
||||
.id, (err, color) => {
|
||||
if (!err) {
|
||||
var cos = JSON.stringify(color);
|
||||
callback.callback(cos)
|
||||
} else {
|
||||
callback.callback(err.message)
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
export function red(color: number): number {
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"module": {
|
||||
"name": "imageknife",
|
||||
"type": "har",
|
||||
"deviceTypes": [
|
||||
"default",
|
||||
"tablet"
|
||||
],
|
||||
"uiSyntax": "ets"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"string": [
|
||||
{
|
||||
"name": "page_show",
|
||||
"value": "page from npm package"
|
||||
}
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue