HarmonyOS 鸿蒙Next app图片拼接:实现两张图片拼接生成一张图片的功能,麻烦提供demo参考
HarmonyOS 鸿蒙Next app图片拼接:实现两张图片拼接生成一张图片的功能,麻烦提供demo参考 我们app需要实现两张图片拼接生成一张图片的功能,麻烦提供demo参考 app图片拼接
3 回复
请参考如下demo:
Index.ets
import { common } from '@kit.AbilityKit';
import { BusinessError, request } from '@kit.BasicServicesKit';
import fs from '@ohos.file.fs';
import { fileUri } from '@kit.CoreFileKit';
import { joinPicture } from '../pages/JoinPicture'
import { photoAccessHelper } from '@kit.MediaLibraryKit';
import { image } from '@kit.ImageKit';
@Component
struct Index5 {
@State imageUri: string = '';
@State combineImageUri: string = '';
context = this.context as common.UIAbilityContext;
filePath = this.context.filesDir + '/test.jpg';
combinePath = this.context.filesDir + '/combine.jpg';
saveButtonOptions: SaveButtonOptions = {
icon: SaveIconStyle.FULL_FILLED,
text: SaveDescription.SAVE_IMAGE,
buttonType: ButtonType.Capsule
} // 设置安全控件按钮属性
onPageShow(): void {
this.checkImageExist()
}
checkImageExist(notExistCallback?: Function) {
fs.access(this.filePath).then((res: boolean) => {
if (res) {
console.info("PictureJoinTogether file exists");
this.imageUri = fileUri.getUriFromPath(this.filePath);
} else {
console.info("PictureJoinTogether file not exists");
if (notExistCallback) {
notExistCallback()
}
}
}).catch((err: BusinessError) => {
console.info("PictureJoinTogether access failed with error message: " + err.message + ", error code: " + err.code);
});
}
// 只是为了分享图片,随便找个图片下载
downloadFile(callback: Function) {
this.checkImageExist(() => {
request.downloadFile(this.context, {
url: 'https://image.baidu.com/search/down?tn=download&word=download&ie=utf8&fr=detail&url=http%3A%2F%2Fpic1.win4000.com%2Fwallpaper%2F2019-11-22%2F5dd7afa7df0fc.jpg&thumburl=https%3A%2F%2Fimg1.baidu.com%2Fit%2Fu%3D2205810988%2C4283060315%26fm%3D253%26fmt%3Dauto%26app%3D138%26f%3DJPEG%3Fw%3D800%26h%3D500',
filePath: this.filePath,
background: true
}).then((downloadTask: request.DownloadTask) => {
downloadTask.on('progress', (receivedSize: number, totalSize: number) => {
console.info("PictureJoinTogether download receivedSize:" + receivedSize + " totalSize:" + totalSize);
});
downloadTask.on('complete', () => {
console.info('PictureJoinTogether download complete');
callback()
})
}).catch((err: BusinessError) => {
console.error(`PictureJoinTogether Invoke downloadTask failed, code is ${err.code}, message is ${err.message}`);
});
})
}
build() {
Column({space: 10}) {
Button('下载图片')
.onClick(() => {
if (this.imageUri !== '') {
return;
}
this.downloadFile(() => {
this.imageUri = fileUri.getUriFromPath(this.filePath);
})
}
Image(this.imageUri)
.width(200)
.height(200)
.backgroundColor(Color.Gray)
Button('合并图片并保存到应用内')
.onClick(() => {
joinPicture.join([this.filePath, this.filePath], this.combinePath, () => {
this.combineImageUri = fileUri.getUriFromPath(this.combinePath);
})
})
Image(this.combineImageUri)
.width(400)
.height(200)
.backgroundColor(Color.Gray)
// 通过安全控件保存应用图片到图库
SaveButton(this.saveButtonOptions)
.onClick(async (event, result: SaveButtonOnClickResult) => {
if (result === SaveButtonOnClickResult.SUCCESS) {
try {
const context = getContext();
const phAccessHelper = photoAccessHelper.getPhotoAccessHelper(context);
const uri = await phAccessHelper.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');
console.info('createAsset successfully, uri: ' + uri);
const file = await fs.open(uri, fs.OpenMode.READ_WRITE);
const imageSource = image.createImageSource(this.combinePath);
const imageInfo = await imageSource.getImageInfo();
const opts: image.DecodingOptions = {
editable: true,
desiredPixelFormat: image.PixelMapFormat.BGRA_8888,
desiredSize: { width: imageInfo.size.width, height: imageInfo.size.height }
};
const pixelMap = await imageSource.createPixelMap(opts);
const imagePackerApi: image.ImagePacker = image.createImagePacker();
let packOpts: image.PackingOption = { format: "image/jpeg", quality: 100 };
const packingArrayBuffer = await imagePackerApi.packing(pixelMap, packOpts);
console.info('packing succeeded.');
fs.writeSync(file.fd, packingArrayBuffer, { offset: 0 })
fs.closeSync(file.fd)
} catch (err) {
console.error('createAsset failed, message = ', err);
}
} else {
console.error('SaveButtonOnClickResult createAsset failed');
}
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
}
JoinPicture.ets
import { image } from '@kit.ImageKit';
import fs from '@ohos.file.fs';
class JoinPicture {
/**
* RGBA与BGRA编码互换,前后统一编码后,就不需要转换了
* @param data
* @returns
*/
rgba2BGRA(data: ArrayBuffer): ArrayBuffer {
let length: number = data.byteLength;
let tempBuffer: ArrayBuffer = new ArrayBuffer(length);
let rgbaData = new DataView(data);
let bgraData = new DataView(tempBuffer);
for (let i = 0; i < length; i += 4) {
bgraData.setUint8(i, rgbaData.getUint8(i + 2));
bgraData.setUint8(i + 1, rgbaData.getUint8(i + 1));
bgraData.setUint8(i + 2, rgbaData.getUint8(i));
bgraData.setUint8(i + 3, rgbaData.getUint8(i + 3));
}
return bgraData.buffer
}
// 这里只考虑横向排列拼接,且每张小图的高度一致
async join(picturePaths: Array<string>, joinPath: string, callback: Function) {
try {
if (picturePaths.length < 2) {
console.info('PictureJoinTogether 需要拼接的图片数量不足')
return;
}
const tempPath = picturePaths[0];
const imageSource = image.createImageSource(tempPath);
const imageInfo = await imageSource.getImageInfo();
const singleWidth = imageInfo.size.width;
const singleHeight = imageInfo.size.height;
const combineOpts: image.InitializationOptions = {
alphaType: 0,
editable: true,
pixelFormat: image.PixelMapFormat.BGRA_8888,
size: { width: singleWidth * picturePaths.length, height: singleHeight }
}
const singleOpts: image.DecodingOptions = {
editable: true,
desiredPixelFormat: image.PixelMapFormat.BGRA_8888,
desiredSize: { width: singleWidth, height: singleHeight }
};
const combineColor = new ArrayBuffer(combineOpts.size.width * combineOpts.size.height * 4);
let singleColor = new ArrayBuffer(singleOpts.desiredSize!.width * singleOpts.desiredSize!.height * 4);
const newPixelMap = await image.createPixelMap(combineColor, combineOpts);
for (let x = 0; x < picturePaths.length; x++) {
//读取小图
//图片应用沙箱路径
let singlePath = picturePaths[x];
let imageSource = image.createImageSource(singlePath);
const singlePixelMap = await imageSource.createPixelMap(singleOpts);
await singlePixelMap.readPixelsToBuffer(singleColor);
//写入大图
let area: image.PositionArea = {
pixels: singleColor,
offset: 0,
stride: singleWidth * 4,
region: {
size: { height: singleHeight, width: singleWidth },
x: singleWidth * x,
y: 0
}
}
await newPixelMap.writePixels(area);
}
let combinePixelMap = newPixelMap;
//保存大图
const saveResult = await this.save(combinePixelMap, joinPath)
saveResult && callback();
} catch (err) {
console.error('PictureJoinTogether join error: ' + JSON.stringify(err))
}
}
async save(pixelMap: image.PixelMap | undefined, path: string) {
if (pixelMap === undefined) {
return false;
}
const imagePackerApi: image.ImagePacker = image.createImagePacker();
let packOpts: image.PackingOption = { format: "image/jpeg", quality: 100 };
const packingArrayBuffer = await imagePackerApi.packing(pixelMap, packOpts);
console.info('packing succeeded.');
let file = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE);
fs.writeSync(file.fd, packingArrayBuffer, { offset: 0 })
fs.closeSync(file.fd)
return true
}
}
export const joinPicture = new JoinPicture()
更多关于HarmonyOS 鸿蒙Next app图片拼接:实现两张图片拼接生成一张图片的功能,麻烦提供demo参考的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
使用canvas可以实现,
在HarmonyOS中实现两张图片拼接生成一张图片的功能,可以通过Canvas类来完成。以下是一个简单的示例代码,展示如何实现这一功能:
// 假设你已经有了两张Bitmap对象,bitmap1和bitmap2
Bitmap resultBitmap = Bitmap.createBitmap(
bitmap1.getWidth() + bitmap2.getWidth(), // 新Bitmap的宽度
Math.max(bitmap1.getHeight(), bitmap2.getHeight()), // 新Bitmap的高度,取两张图片中的最大值
Bitmap.Config.ARGB_8888 // 配置
);
Canvas canvas = new Canvas(resultBitmap);
canvas.drawBitmap(bitmap1, 0, 0, null); // 将第一张图片绘制到左上角
canvas.drawBitmap(bitmap2, bitmap1.getWidth(), 0, null); // 将第二张图片绘制到第一张图片的右侧
// 此时resultBitmap就是拼接后的图片
// 你可以将其保存到文件中,或者用于其他显示需求
注意,上述代码假设你已经有了bitmap1
和bitmap2
这两个Bitmap对象。在实际应用中,你可能需要从资源文件、网络或其他来源加载这些图片。
如果你需要在UI中显示拼接后的图片,可以使用ImageView等组件来展示resultBitmap
。
如果问题依旧没法解决请联系官网客服,官网地址是 https://www.itying.com/category-93-b0.html