mã nguồn : sharePhoto
Mã nguồn : main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
import { defineCustomElements } from '@ionic/pwa-elements/loader';
defineCustomElements(window);
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
HttpClientModule,
],
providers: [{ provide: RouteReuseStrategy,
useClass: IonicRouteStrategy }],
bootstrap: [AppComponent],
})
export class AppModule {}
photo.service.ts
import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http';
export interface ApiImage{
_id: string;
name: string;
createdAt: Date;
url: string;
}
@Injectable({
providedIn: 'root'
})
export class PhotoService {
url ='http://localhost:8100/home';
constructor(private http: HttpClient) {
}
uploadImage(blobData, name, ext){
const formData = new FormData();
formData.append('file',blobData, `myimage.${ext}`);
formData.append('name',name);
return this.http.post(`${this.url}/image`, formData);
}
uploadImageFile(file: File){
const formData = new FormData();
formData.append('file',file, file.name);
formData.append('name',file.name);
return this.http.post(`${this.url}/image`, formData);
}
getImages(){
return this.http.get<ApiImage[]>(`${this.url}/image`);
}
deleteImages(id){
return this.http.delete(`${this.url}/image/${id}`);
}
}
home.page.ts
import { Component, ElementRef, ViewChild } from '@angular/core';
import { ApiImage, PhotoService } from '../services/photo.service';
import { Platform, ActionSheetController } from '@ionic/angular';
import { CameraResultType, CameraSource, Plugins } from '@capacitor/core';
const { Camera } = Plugins;
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
images: ApiImage[] = [];
@ViewChild('fileInput', {static: false})fileInput:ElementRef;
constructor(private api: PhotoService,private actionSheetCtrl: ActionSheetController,private plt: Platform) {
this.loadImage();
}
loadImage(){
this.api.getImages().subscribe(images => {
this.images = images;
console.log(this.images);
});
}
deleteImage(image: ApiImage, index){
this.api.deleteImages(image._id).subscribe(res => {
this.images.splice(index,1);
});
}
async selectImageSource(){
const buttons = [
{
text: 'Take Photo',
icon: 'camera',
handler:() =>{
this.addImage(CameraSource.Camera);
}
},
{
text:'Choose From Photos',
icon:'image',
handler:() =>{
this.addImage(CameraSource.Photos);
}
}
];
if(!this.plt.is('hybrid')){
buttons.push({
text: 'Choose a File',
icon: 'attach',
handler: () => {
this.fileInput.nativeElement.click();
}
});
}
const actionSheet = await this.actionSheetCtrl.create({
header: 'Select Image Source',
buttons
});
await actionSheet.present();
}
uploadFile( event: EventTarget){
const eventObj: MSInputMethodContext = event as MSInputMethodContext;
const target: HTMLInputElement = eventObj.target as HTMLInputElement;
const file: File = target.files[0];
this.api.uploadImageFile(file).subscribe((newImage: ApiImage) => {
this.images.push(newImage);
});
}
async addImage( source: CameraSource){
const image = await Camera.getPhoto({
quality: 100,
allowEditing: true,
resultType: CameraResultType.Base64,
source
});
console.log('image: ',image);
const blobData = this.b64toBlod(image.base64String, `image/${image.format}`);
const imageName = 'Give me a name';
this.api.uploadImage(blobData,imageName, image.format).subscribe((newImage: ApiImage) => {
this.images.push(newImage);
});
}
b64toBlod(b64Data, contentType ='', sliceSize=512){
const byteCharacters = atob(b64Data);
const byteArrays = [];
for(let offset = 0; offset < byteCharacters.length; offset += sliceSize){
const slice = byteCharacters.slice(offset,offset + sliceSize);
const byteNumbers = new Array(slice.length);
for(let i = 0; i<slice.length; i++){
byteNumbers[i] = slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArrays);
}
const blob = new Blob(byteArrays, {type: contentType});
return blob;
}
}
home.page.html
<ion-header >
<ion-toolbar>
<ion-title>
Devctic Images
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<ion-row>
<ion-col
size="6"
*ngFor="let img of images; let i=index"
class="ion-text-center"
>
<ion-lanel>
{{ img.name }}
<p>{{ img.createdAt | date:'short' }}</p>
</ion-lanel>
<ion-img [src]="img.url"> </ion-img>
<ion-fab vertival=botton horizontal="end">
<ion-fab-button
color="danger"
size="small"
(click)="deleteImage(img, i)"
>
<ion-icon name="trach-outline"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-col>
</ion-row>
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<input type="file"
#fileInput
(change)="uploadFile($event)"
hidden="true"
accept="image/*"
/>
<ion-fab-button (click)="selectImageSource()">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-content>
Mã nguồn academyShare
Mã nguồn : main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
import { defineCustomElements} from "@ionic/pwa-elements/loader";
defineCustomElements(window);
app.module.ts
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule} from "@angular/common/http";
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
HttpClientModule
],
providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
bootstrap: [AppComponent],
})
export class AppModule {}
home.page.ts
import { Component } from '@angular/core';
import {HttpClient} from "@angular/common/http";
import {Plugins, CameraResultType, CameraSource} from '@capacitor/core';
const {Share, FileSharer} = Plugins;
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
constructor(private http: HttpClient) {}
async basicShare(){
await Share.share({
title: 'Learn',
text: 'Check out',
url: 'http://192.168.1.31:8100/'
});
}
async shareImage(){
const image = await Plugins.Camera.getPhoto({
quality: 100,
allowEditing: false,
resultType: CameraResultType.Uri,
source: CameraSource.Camera
});
await Share.share({
title: 'Learn',
url: image.path,
});
}
async shareLocalFile(){
this.http.get('../../assets/img/1.png', { responseType :'blob'})
.subscribe(res => {
const reader = new FileReader();
reader.onloadend = () =>{
const result = reader.result as string;
const base64Data = result.split(',')[1];
FileSharer.share({
filename: '1.png',
base64Data,
contentType: 'application/png'
});
}
reader.readAsDataURL(res);
});
}
}
home.page.html
<ion-header>
<ion-toolbar>
<ion-title>
Academy Share
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<ion-button expand="full" (click)="basicShare()" >BasicShare</ion-button>
<ion-button expand="full" (click)="shareImage()" >ShareImage</ion-button>
<ion-button expand="full" (click)="shareLocalFile()" >ShareLocalFile</ion-button>
</ion-content>
Mã nguồn dedacticImages
Mã nguồn : main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import { defineCustomElements } from '@ionic/pwa-elements/loader';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
defineCustomElements(window);
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
HttpClientModule
],
providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
bootstrap: [AppComponent],
})
export class AppModule {}
photo.service.ts
import { Injectable } from '@angular/core';
import { HttpClient} from '@angular/common/http';
export interface ApiImage{
_id:string;
name: string;
createAt: Date;
url:string;
}
@Injectable({
providedIn: 'root'
})
export class ApiService {
url = 'http://localhost:8100';
constructor(private http: HttpClient) { }
uploadImage(blobData, name, ext){
const formData = new FormData();
formData.append('file', blobData, `myimage.${ext}`);
formData.append('name', name);
return this.http.post(`${this.url}.image`, formData);
}
uploadImageFile(file : File){
const formData = new FormData();
formData.append('file', file, file.name);
formData.append('name', file.name);
return this.http.post(`${this.url}.image`, formData);
}
getImages(){
return this.http.get<ApiImage[]>(`${this.url}/image`);
}
deleteImage(id){
return this.http.delete(`${this.url}/image/${id}`);
}
}
home.page.ts
import { Component, ElementRef, ViewChild } from '@angular/core';
import { CameraResultType, CameraSource, Plugins } from '@capacitor/core';
import { ActionSheetController, Platform } from '@ionic/angular';
import { ApiImage, ApiService } from '../services/api.service';
const { Camera } = Plugins;
@Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
images: ApiImage[] = [];
@ViewChild('fileInput', {static: true})fileInput: ElementRef;
constructor(private api: ApiService,private plt:Platform,private actionSheetCtrl: ActionSheetController) {
this.loadImages();
}
loadImages(){
this.api.getImages().subscribe(images => {
this.images = images;
console.log(this.images)
});
}
deleteImage(image: ApiImage,index){
this.api.deleteImage(image._id).subscribe(res => {
this.images.splice(index,1);
})
}
async selectImageSource(){
const buttons=[
{
text:'Take Photo',
icon: 'camera',
handle: () =>{
this.addImage(CameraSource.Camera);
}
},
{
text:'Choose From Photos photo',
icon: 'image',
handle:()=>{
this.addImage(CameraSource.Photos);
}
}
];
if(!this.plt.is('hybrid')){
buttons.push({
text: 'choose a File',
icon: 'attach',
handle: ()=>{
this.fileInput.nativeElement.click();
}
});
}
const actionSheet = await this.actionSheetCtrl.create({
header:'select Image Source',
buttons
});
await actionSheet.present();
}
uploadFile(event: EventTarget){
const eventObj: MSInputMethodContext=event as MSInputMethodContext;
const target: HTMLInputElement = eventObj.target as HTMLInputElement;
const file: File = target.files[0];
this.api.uploadImageFile(file).subscribe((newImage: ApiImage) => {
this.images.push(newImage);
});
}
async addImage(source: CameraSource){
const image = await Camera.getPhoto({
quality: 100,
allowEditing: false,
resultType: CameraResultType.Base64,
source
});
const blobData = this.b64toBlod(image.base64String,`image/${image.format}`);
const imageName = 'give ma a name';
this.api.uploadImage(blobData,imageName,image.format).subscribe((newImage: ApiImage) => {
this.images.push(newImage);
});
}*
b64toBlod(b64Data,contentType='', sliceSize=512){
const byteCharacters = atob(b64Data);
const byteArrays = [];
for(let offset = 0; offset < byteCharacters.length; offset += sliceSize){
const slice=byteCharacters.slice(offset,offset+sliceSize);
const byteNumbers = new Array(slice.length);
for(let i = 0; i<slice.length;i++){
byteNumbers[i]=slice.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
byteArrays.push(byteArray)
}
const blob = new Blob(byteArrays, {type: contentType});
return blob;
}
}
home.page.html
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>
Devctic Images
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<ion-row>
<ion-col size=6
*ngFor="let img of images; let i = index;">
<ion-label>
{{img.name}}
<p>{{img.createAt | date:'short' }}</p>
</ion-label>
<img [src]="img.url"/>
<ion-fab vertical = "buttom" horizontal="end">
<ion-fab-button
color="danger"
size="small"
(click)="deleteImage(img,i)"
>
<ion-icon name="trash-outline"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-col>
</ion-row>
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<input
type="file"
#fileInput
(change)="uploadFile($event)"
hidden="true"
accept="image/*"
/>
<ion-fab-button (click)="selectImageSource()">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-content>
Mã nguồn photo-gallery
Mã nguồn : main.ts
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
if (environment.production) {
enableProdMode();
}
platformBrowserDynamic().bootstrapModule(AppModule)
.catch(err => console.log(err));
import { defineCustomElements } from '@ionic/pwa-elements/loader';
// Call the element loader after the platform has been bootstrapped
defineCustomElements(window);
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule} from "@angular/common/http";
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule,
IonicModule.forRoot(),
AppRoutingModule,
HttpClientModule
],
providers: [{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }],
bootstrap: [AppComponent],
})
export class AppModule {}
tabs.module.ts
import { Component } from '@angular/core';
import { FileSharer } from '@byteowls/capacitor-filesharer';
import { registerWebPlugin } from '@capacitor/core';
@Component({
selector: 'app-tabs',
templateUrl: 'tabs.page.html',
styleUrls: ['tabs.page.scss']
})
export class TabsPage {
constructor() {
registerWebPlugin(FileSharer);
}
}
tabs.module.html
<ion-tabs>
<ion-tab-bar slot="bottom">
<ion-tab-button tab="tab1">
<ion-icon name="images-outline"></ion-icon>
<ion-label>Gallery</ion-label>
</ion-tab-button>
<ion-tab-button tab="tab2">
<ion-icon name="image"></ion-icon>
<ion-label>Photos</ion-label>
</ion-tab-button>
<ion-tab-button tab="tab3">
<ion-icon name="person-add-sharp"></ion-icon>
<ion-label>About</ion-label>
</ion-tab-button>
</ion-tab-bar>
</ion-tabs>
tabs3.page.html
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>
Tab 3
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<ion-card>
<img src="../../assets/img/a.jpg"/>
<ion-card-header>
<ion-card-subtitle>Lê Sỹ Hùng</ion-card-subtitle>
<ion-card-title>MSSV: 1812767</ion-card-title>
<ion-card-title>Lớp: CTK42</ion-card-title>
</ion-card-header>
<ion-card-content>
Thích tìm hiểu những ngôn ngữ mới,tạo ra những phần mềm hữu ích.
</ion-card-content>
</ion-card>
</ion-content>
tab2.page.ts
import { Component } from '@angular/core';
import { PhotoService } from '../services/photo.service';
import { ActionSheetController } from '@ionic/angular';
@Component({
selector: 'app-tab2',
templateUrl: 'tab2.page.html',
styleUrls: ['tab2.page.scss']
})
export class Tab2Page {
constructor(public photoService: PhotoService,
public actionSheetController: ActionSheetController) {
}
async ngOnInit() {
await this.photoService.loadSaved();
}
addPhotoToGallery() {
this.photoService.addNewToGallery();
}
presentActionSheet() {
this.photoService.presentActionSheet();
}
}
tab2.page.html
<ion-header [translucent]="true">
<ion-toolbar>
<IonTitle>
Photo Gallery
</IonTitle>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-grid>
<ion-row>
<ion-col size="6" *ngFor="let photo of photoService.photos; index as position">
<ion-card>
<ion-img [src]="photo.webviewPath"
(click)="this.presentActionSheet()"></ion-img>
</ion-card>
</ion-col>
</ion-row>
</ion-grid>
<ion-fab vertical="bottom" horizontal="center" slot="fixed">
<ion-fab-button (click)="addPhotoToGallery()">
<ion-icon name="camera"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-content>
tab1.page.ts
import { Component } from '@angular/core';
import { PhotoService } from '../services/photo.service';
@Component({
selector: 'app-tab1',
templateUrl: 'tab1.page.html',
styleUrls: ['tab1.page.scss']
})
export class Tab1Page {
constructor(public photoService: PhotoService) { }
}
tab1.page.html
<ion-header [translucent]="true">
<ion-toolbar>
<IonTitle>
Photo Gallery Edit
</IonTitle>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-grid>
<ion-row>
<ion-col size="6"
*ngFor="let photo of photoService.photos; index as position">
<ion-img [src]="photo.webviewPath"></ion-img>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>
photo.service.ts
import { Injectable } from '@angular/core';
import { Plugins, CameraResultType, Capacitor, FilesystemDirectory,
CameraPhoto, CameraSource } from '@capacitor/core';
import { Platform } from '@ionic/angular';
import { ActionSheetController } from '@ionic/angular';
const { Camera,Share, Filesystem, Storage,FileSharer } = Plugins;
import {HttpClient} from "@angular/common/http";
@Injectable({
providedIn: 'root'
})
export class PhotoService {
public photos: Photo[] = [];
private PHOTO_STORAGE: string = "photos";
private platform: Platform;
constructor(platform: Platform,
public actionSheetController: ActionSheetController,
private http: HttpClient) {
this.platform = platform;
}
public async addNewToGallery() {
Storage.set({
key: this.PHOTO_STORAGE,
value: JSON.stringify(this.photos)
});
// Take a photo
const capturedPhoto = await Camera.getPhoto({
resultType: CameraResultType.Uri, // file-based data; provides best performance
source: CameraSource.Camera, // automatically take a new photo with the camera
quality: 100 // highest quality (0 to 100)
});
// Save the picture and add it to photo collection
const savedImageFile = await this.savePicture(capturedPhoto);
this.photos.unshift(savedImageFile);
}
// Save picture to file on device
private async savePicture(cameraPhoto: CameraPhoto) {
// Convert photo to base64 format, required by Filesystem API to save
const base64Data = await this.readAsBase64(cameraPhoto);
// Write the file to the data directory
const fileName = new Date().getTime() + '.jpeg';
const savedFile = await Filesystem.writeFile({
path: fileName,
data: base64Data,
directory: FilesystemDirectory.Data
});
if (this.platform.is('hybrid')) {
return {
filepath: savedFile.uri,
webviewPath: Capacitor.convertFileSrc(savedFile.uri),
};
}
else {
// Use webPath to display the new image instead of base64 since it's
// already loaded into memory
return {
filepath: fileName,
webviewPath: cameraPhoto.webPath
};
}
}
private async readAsBase64(cameraPhoto: CameraPhoto) {
// "hybrid" will detect Cordova or Capacitor
if (this.platform.is('hybrid')) {
// Read the file into base64 format
const file = await Filesystem.readFile({
path: cameraPhoto.path
});
return file.data;
}
else {
// Fetch the photo, read as a blob, then convert to base64 format
const response = await fetch(cameraPhoto.webPath);
const blob = await response.blob();
return await this.convertBlobToBase64(blob) as string;
}
}
convertBlobToBase64 = (blob: Blob) => new Promise((resolve, reject) => {
const reader = new FileReader;
reader.onerror = reject;
reader.onload = () => {
resolve(reader.result);
};
reader.readAsDataURL(blob);
});
public async loadSaved() {
// Retrieve cached photo array data
const photoList = await Storage.get({ key: this.PHOTO_STORAGE });
this.photos = JSON.parse(photoList.value) || [];
// Easiest way to detect when running on the web:
// “when the platform is NOT hybrid, do this”
if (!this.platform.is('hybrid')) {
// Display the photo by reading into base64 format
for (let photo of this.photos) {
// Read each saved photo's data from the Filesystem
const readFile = await Filesystem.readFile({
path: photo.filepath,
directory: FilesystemDirectory.Data
});
// Web platform only: Load the photo as base64 data
photo.webviewPath = `data:image/jpeg;base64,${readFile.data}`;
}
}
}
public async sharePhoto(){
const image = await Plugins.Camera.getPhoto({
quality: 100,
allowEditing: false,
resultType: CameraResultType.Uri,
source: CameraSource.Camera
});
await Share.share({
title: 'Learn',
url: image.path,
});
}
public async shareLocalFile(){
this.http.get('../img/1.png', { responseType :'blob'})
.subscribe(res => {
const reader = new FileReader();
reader.onloadend = () =>{
const result = reader.result as string;
const base64Data = result.split(',')[1];
FileSharer.share({
filename: '1.png',
base64Data,
contentType: 'application/png'
});
}
reader.readAsDataURL(res);
});
}
public async deletePhoto(){
}
async presentActionSheet() {
const actionSheet = await this.actionSheetController.create({
header: 'Share Photo',
cssClass: 'my-custom-class',
buttons: [{
text: 'Share',
icon: 'arrow-redo-sharp',
handler: () => {
this.sharePhoto();
console.log('Share clicked');
}
},{
text: 'Share File local',
icon: 'arrow-redo-sharp',
handler: () => {
this.shareLocalFile();
console.log('Share clicked');
}
},
// {
// text: 'Delete',
// role: 'destructive',
// icon: 'trash',
// handler: () => {
// this.deletePhoto()
// console.log('Delete clicked');
// }
// },
{
text: 'Cancel',
icon: 'close',
role: 'cancel',
handler: () => {
console.log('Cancel clicked');
}
}]
});
await actionSheet.present();
const { role } = await actionSheet.onDidDismiss();
console.log('onDidDismiss resolved with role', role);
}
}
export interface Photo {
filepath: string;
webviewPath: string;
}

0 Nhận xét