Flex Image控件显示BMP图片实现方法

本文介绍了一种使用2进制载入BMP文件,并将其转换为BitmapData以供Image控件显示的方法。通过Flex应用实例展示了从读取BMP文件到图像显示的全过程。

主要原理是使用2进制载入,再按24位BMP文件格试进行读取并转换成BitmapData再显示出来,只要读入BMP图片转换成二进制,再转成BitmapData,最后把获取位图数据的Bitmap传给Image源,让Image控件显示出来。
请看下面一个Flex工程:
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
       <![CDATA[
  
         import mx.core.UIComponent;
         import mx.core.BitmapAsset;
         //导入BMPDecoder
      import imageDecoder.BMPDecoder;
         private function showimage():void {
             loadBMPFile("../test.bmp");
         }
         private function loadBMPFile( url:String ):void {
var loader:URLLoader = new URLLoader();
    //指定loader以二进制返回数据
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener( Event.COMPLETE, onCompleteLoad );
loader.load( new URLRequest( url ) );
   }
private function onCompleteLoad( e:Event ):void {
   var loader:URLLoader = e.target as URLLoader;
   var decoder:BMPDecoder = new BMPDecoder();
   //将二进制数据转换成BitmapData
   var bd:BitmapData = decoder.decode( loader.data );
   //用来显示效果的Bitmap获取位图数据,图片平滑
   var myBitmap:Bitmap = new Bitmap(bd,"auto",true);
   myImage.source=myBitmap;
}
       ]]>
</mx:Script>

<mx:Button
       id="showImage"
       label="showimage"
       click="showimage();"/>
      
<mx:Image id="myImage" />       
</mx:Application>

使用ele-plus的图片上传组件实现图片和cad文件的分开上传和显示 在上传时判断文件类型 如果是cad则显示图片控件的下方 显示名称 如果是图片则直接回显在图片上传组件上<template> <div class="upload-box"> <el-upload v-model:file-list="fileList" accept="*/*" :action="uploadUrl" :before-upload="beforeUpload" :class="['upload', drag ? 'no-border' : '']" :disabled="disabled" :drag="drag" :data="uploadData" :headers="headers" :limit="limit" :multiple="true" :on-error="uploadError" :on-exceed="handleExceed" :on-success="uploadSuccess" list-type="picture-card" :show-file-list="true" > <div class="upload-empty"> <slot name="empty"> <Icon icon="ep:plus" /> </slot> </div> <template #file="{ file }"> <img :src="file.url" class="upload-image" /> <div class="upload-handle" @click.stop> <div class="handle-icon" @click="handlePictureCardPreview(file)"> <Icon icon="ep:zoom-in" /> <span>查看</span> </div> <div v-if="!disabled" class="handle-icon" @click="handleRemove(file)"> <Icon icon="ep:delete" /> <span>删除</span> </div> </div> </template> </el-upload> <!-- 上传提示 --> <div class="el-upload__tip" v-if="showTip"> <!-- <template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template> --> <template v-if="fileType"> 只能上传 <b style="color: #f56c6c">{{ showFileType.join('/') }}</b> </template> 的文件 </div> <div class="el-upload__tip"> <slot name="tip"></slot> </div> <el-image-viewer v-if="imgViewVisible" :url-list="viewImageUrlList" :initial-index="currentImageIndex" @close="imgViewVisible = false" /> </div> </template> <script lang="ts" setup> import type { UploadFile, UploadProps, UploadUserFile } from 'element-plus' import { ElNotification } from 'element-plus' import { getAccessToken } from '@/utils/auth' import { propTypes } from '@/utils/propTypes' // import { useUpload } from '@/components/UploadFile/src/useUpload' defineOptions({ name: 'UploadImgs' }) const message = useMessage() // 消息弹窗 type FileTypes = | 'image/apng' | 'image/bmp' | 'image/gif' | 'image/jpeg' | 'image/pjpeg' | 'image/png' | 'image/svg+xml' | 'image/tiff' | 'image/webp' | 'image/x-icon' | 'application/dwg' const props = defineProps({ modelValue: propTypes.oneOfType<string | string[]>([String, Array<String>]).isRequired, drag: propTypes.bool.def(true), // 是否支持拖拽上传 ==> 非必传(默认为 true) disabled: propTypes.bool.def(false), // 是否禁用上传组件 ==> 非必传(默认为 false) limit: propTypes.number.def(20), // 最大图片上传数 ==> 非必传(默认为 20张) //fileSize: propTypes.number.def(5), // 图片大小限制 ==> 非必传(默认为 5M) fileType: propTypes.array.def(['image/jpeg', 'image/png', 'image/gif', 'image/jpg','application/dwg']), // 图片类型限制 ==> 非必传(默认为 ["image/jpeg", "image/png", "image/gif"]) height: propTypes.string.def('150px'), // 组件高度 ==> 非必传(默认为 150px) width: propTypes.string.def('150px'), // 组件宽度 ==> 非必传(默认为 150px) borderradius: propTypes.string.def('8px'), // 组件边框圆角 ==> 非必传(默认为 8px) data: propTypes.object.def({}), // 添加 data 属性 // 是否显示提示 isShowTip: { type: Boolean, default: true }, showFileType: propTypes.array.def(['.jpeg', '.png', '.svg','.dwg']) }) const uploadData = computed(() => { return { tableName: props.data?.tableName || '' // 确保 tableName 被正确传递 } }) // const baseUrl = import.meta.env.VITE_API_URL // 请求路径 const uploadUrl = import.meta.env.VITE_UPLOAD_URL // 上传路径 const headers = { Authorization: 'Bearer ' + getAccessToken() } // const { uploadUrl, httpRequest } = useUpload() const fileList = ref<UploadUserFile[]>([]) // const uploadList = ref([]) const uploadNumber = ref<number>(0) const uploadList = ref<UploadUserFile[]>([]) // 是否显示提示 const showTip = computed(() => { //return props.isShowTip && (props.fileType || props.fileSize) return props.isShowTip && props.fileType }) /** * @description 文件上传之前判断 * @param rawFile 上传的文件 * */ const beforeUpload: UploadProps['beforeUpload'] = (rawFile) => { // const imgSize = rawFile.size / 1024 / 1024 < props.fileSize // if (!imgSize) // ElNotification({ // title: '温馨提示', // message: `上传图片大小不能超过 ${props.fileSize}M!`, // type: 'warning' // }) // const imgType = props.fileType // if (!imgType.includes(rawFile.type as FileTypes)) // ElNotification({ // title: '温馨提示', // message: '上传图片不符合所需的格式!', // type: 'warning' // }) uploadNumber.value++ return true //return imgType.includes(rawFile.type as FileTypes) && imgSize //return imgType.includes(rawFile.type as FileTypes) } // 图片上传成功 interface UploadEmits { (e: 'update:modelValue', value: string[]): void } const emit = defineEmits<UploadEmits>() // const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => { // console.log('res.data:', res.data); // message.success('上传成功') // // 确保res.data是字符串类型 // if (typeof res.data === 'string') { // console.log('res.data:', res.data); // // 删除自身 // const index = fileList.value.findIndex((item) => item.response?.data === res.data) // fileList.value.splice(index, 1) // uploadList.value.push({ name: res.data, url: res.data }) // if (uploadList.value.length == uploadNumber.value) { // fileList.value.push(...uploadList.value) // uploadList.value = [] // uploadNumber.value = 0 // emitUpdateModelValue() // } // } else { // console.log('Invalid response data:', res.data) // } // } // const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => { // message.success('上传成功') // // 确保响应数据有效 // if (res && typeof res.data === 'string') { // // 删除临时上传记录 // const index = fileList.value.findIndex((item) => item.response?.data === res.data) // if (index !== -1) { // fileList.value.splice(index, 1) // } // // 添加到已上传列表 // uploadList.value.push({ // name: res.data.substring(res.data.lastIndexOf('/') + 1), // url: `${res.data}?token=${token}` // // url: `${res.data}` // }) // // 检查是否所有文件都已上传完成 // if (uploadList.value.length === uploadNumber.value) { // fileList.value.push(...uploadList.value) // uploadList.value = [] // uploadNumber.value = 0 // emitUpdateModelValue() // } // } else { // console.error('Invalid response data:', res.data) // message.error('上传响应数据格式错误') // } // } // 在 uploadSuccess 函数中修改 URL 构造方式 const uploadSuccess: UploadProps['onSuccess'] = (res: any): void => { console.log('fileList',fileList.value); message.success('上传成功') if (res && typeof res.data === 'string') { const index = fileList.value.findIndex((item) => item.response?.data === res.data) if (index !== -1) { fileList.value.splice(index, 1) } // 使用 getAccessToken() 获取 token const token = getAccessToken() uploadList.value.push({ name: res.data.substring(res.data.lastIndexOf('/') + 1), // url: token ? `${res.data}?token=${token}` : res.data url: token ? `${res.data}` : res.data // url: res.data.url }) if (uploadList.value.length === uploadNumber.value) { fileList.value.push(...uploadList.value) uploadList.value = [] uploadNumber.value = 0 emitUpdateModelValue() } } else { console.error('Invalid response data:', res.data) message.error('上传响应数据格式错误') } } // 监听模型绑定值变动 watch( () => props.modelValue, (val: string | string[]) => { if (!val) { fileList.value = [] // fix:处理掉缓存,表单重置后上传组件的内容并没有重置 return } fileList.value = [] // 保障数据为空 // fileList.value.push( // ...(val as string[]).map((url) => ({ name: url.substring(url.lastIndexOf('/') + 1), url })) // ) fileList.value.push( ...(val as string[]).map((url) => { if (typeof url === 'string') { return { name: url.substring(url.lastIndexOf('/') + 1), url } } else { // 处理非字符串的 url,可能是抛出错误或返回一个默认值 console.error('Invalid url:', url) return { name: '', url: '' } // 或者其他合适的默认值 } }) ) }, { immediate: true, deep: true } ) // 发送图片链接列表更新 const emitUpdateModelValue = () => { let result: string[] = fileList.value.map((file) => file.url!) emit('update:modelValue', result) } // 删除图片 const handleRemove = (uploadFile: UploadFile) => { fileList.value = fileList.value.filter( (item) => item.url !== uploadFile.url || item.name !== uploadFile.name ) emit( 'update:modelValue', fileList.value.map((file) => file.url!) ) } // 图片上传错误提示 const uploadError = () => { ElNotification({ title: '温馨提示', message: '图片上传失败,请您重新上传!', type: 'error' }) } // 文件数超出提示 const handleExceed = () => { ElNotification({ title: '温馨提示', message: `当前最多只能上传 ${props.limit} 张图片,请移除后上传!`, type: 'warning' }) } // 图片预览 const viewImageUrlList = ref<string[]>([]) const imgViewVisible = ref(false) const currentImageIndex = ref(0) // 新增:当前点击的图片索引 const handlePictureCardPreview = (uploadFile: UploadFile) => { viewImageUrlList.value = fileList.value.map(file => file.url!) // 将所有图片的 URL 存储在数组中 currentImageIndex.value = fileList.value.findIndex(file => file.url === uploadFile.url) // 获取当前点击的图片索引 console.log('currentImageIndex.value',currentImageIndex.value); imgViewVisible.value = true } //获取cookie const getCookie = (name) => { const value = `; ${document.cookie}` const parts = value.split(`; ${name}=`) if (parts.length === 2) { // 如果找到了对应的cookie,返回其值(去除后面的分号和其他可能的属性) return parts.pop().split(';').shift() } // 如果没有找到对应的cookie,返回null或undefined return null } // 获取 accessToken const token = getCookie('accessToken') </script> <style lang="scss" scoped> .is-error { .upload { :deep(.el-upload--picture-card), :deep(.el-upload-dragger) { border: 1px dashed var(--el-color-danger) !important; &:hover { border-color: var(--el-color-primary) !important; } } } } :deep(.disabled) { .el-upload--picture-card, .el-upload-dragger { cursor: not-allowed; background: var(--el-disabled-bg-color) !important; border: 1px dashed var(--el-border-color-darker); &:hover { border-color: var(--el-border-color-darker) !important; } } } .upload-box { .no-border { :deep(.el-upload--picture-card) { border: none !important; } } :deep(.upload) { .el-upload-dragger { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; padding: 0; overflow: hidden; border: 1px dashed var(--el-border-color-darker); border-radius: v-bind(borderradius); &:hover { border: 1px dashed var(--el-color-primary); } } .el-upload-dragger.is-dragover { background-color: var(--el-color-primary-light-9); border: 2px dashed var(--el-color-primary) !important; } .el-upload-list__item, .el-upload--picture-card { width: v-bind(width); height: v-bind(height); background-color: transparent; border-radius: v-bind(borderradius); } .upload-image { width: 100%; height: 100%; object-fit: contain; } .upload-handle { position: absolute; top: 0; right: 0; display: flex; width: 100%; height: 100%; cursor: pointer; background: rgb(0 0 0 / 60%); opacity: 0; box-sizing: border-box; transition: var(--el-transition-duration-fast); align-items: center; justify-content: center; .handle-icon { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 0 6%; color: aliceblue; .el-icon { margin-bottom: 15%; font-size: 140%; } span { font-size: 100%; } } } .el-upload-list__item { &:hover { .upload-handle { opacity: 1; } } } .upload-empty { display: flex; flex-direction: column; align-items: center; font-size: 12px; line-height: 30px; color: var(--el-color-info); .el-icon { font-size: 28px; color: var(--el-text-color-secondary);<template> <el-dialog title="新增图纸" v-model="dialogVisible" :close-on-click-modal="false" @close="handleCancel" width="500px" > <!-- <div class="upload-container"> <div class="file-upload-row"> <div class="file-label"> <span class="required">*</span>图纸 </div> <div class="upload-area-container"> <div class="upload-text"> <UploadImgs v-model="imageDataList" :file-type="['image/png', 'image/jpg','image/svg+xml']" :file-size="20" :width="'100px'" :height="'100px'" :show-delete="true" :show-btn-text="false" /> </div> <span v-if="fileErrors" class="error-message">{{ fileErrors }}</span> </div> </div> </div> --> <el-form ref="formRef" :model="formData" label-width="80px" :rules="formRules" v-loading="formLoading"> <el-row> <el-col :span="24"> <el-form-item label="图纸" prop = 'file'> <UploadImgs v-model="formData.file" :width="'120px'" :height="'120px'" :show-delete="true" :show-btn-text="false" :data = data @change="handleFileChange" /> <!-- 非图片文件列表展示区域 --> <div v-if="nonImageFiles.length > 0" class="non-image-files"> <div class="file-list-title">已上传文件:</div> <div v-for="(file, index) in nonImageFiles" :key="index" class="file-item" > <span class="file-name">{{ file.name }}</span> <el-button type="text" class="delete-btn" @click="handleDeleteFile(index)" > 删除 </el-button> </div> </div> </el-form-item> </el-col> </el-row> </el-form> <template #footer> <el-button @click="handleCancel" class="dialog-btn">取消</el-button> <el-button type="primary" @click="handleConfirm" class="dialog-btn" :disabled="formLoading">确定</el-button> </template> </el-dialog> </template> <script lang="ts" setup> import { ref } from 'vue' import { ElMessage,FormRules } from 'element-plus' import * as api from '@/api/miningAreaDrawing/index' import UploadImgs from '@/components/UploadFile/src/UploadImgs.vue' const data = ref({tableName : 'drawing'}) // 定义props const props = defineProps({ modelValue: { type: Boolean, default: false }, currentParentNode: { type: Object, default: null } }) const departmentId = ref('') // 定义emits const emit = defineEmits(['update:modelValue', 'success', 'cancel']) const formData = ref({ parentId:'', file: [], departmentId:'', name:'' }) const formRules = reactive<FormRules>({ file: [ { required: true, message: '请上传图片', trigger: ['change','blur'] } ] }) const formRef = ref() const formLoading = ref(false) // 用于区分图片和非图片文件 const nonImageFiles = ref([]) const imageFiles = ref([]) // 组件内部状态 const dialogVisible = ref(props.modelValue) const fileErrors = ref('') // 监听modelValue变化 watch(() => props.modelValue, (newVal) => { console.log(newVal) dialogVisible.value = newVal }) // 监听dialogVisible变化,同步到父组件 watch(dialogVisible, (newVal) => { emit('update:modelValue', newVal) }) // 判断是否为图片文件 const isImageFile = (file) => { const imageTypes = ['image/png', 'image/jpg', 'image/jpeg', 'image/gif', 'image/svg+xml'] return imageTypes.includes(file.raw?.type) || imageTypes.includes(file.type) || (file.name && file.name.match(/\.(png|jpg|jpeg|gif|svg)$/i)); } // 处理上传组件的文件变化 const handleFileChange = (files) => { // 分离图片文件和非图片文件 const images = [] const nonImages = [] files.forEach(file => { if (isImageFile(file)) { images.push(file) } else { nonImages.push(file) } }) imageFiles.value = images nonImageFiles.value = nonImages updateFormData() } // 更新表单数据 const updateFormData = () => { // 合并图片文件和非图片文件 formData.value.file = [...imageFiles.value, ...nonImageFiles.value] } // 删除非图片文件 const handleDeleteFile = (index) => { nonImageFiles.value.splice(index, 1) updateFormData() } // 确认上传 const handleConfirm = async() => { // 校验表单 if(!formRef.value) return const valid = await formRef.value.validate() if(!valid) return // 提交请求 formLoading.value = true try { console.log("123") const response = await api.addDrawing({ file: formData.value.file, parentId: props.currentParentNode?.id, departmentId: departmentId.value }) if (response) { ElMessage.success('文件上传成功') dialogVisible.value = false // 通知父组件刷新列表 emit('success') } else { ElMessage.error('文件上传失败: ' + (response?.msg || '未知错误')) } } finally { formLoading.value = false } } // 取消上传 const handleCancel = () => { dialogVisible.value = false formData.value = { parentId:'', file:[], departmentId:'', } formRef.value?.resetFields() fileErrors.value = '' emit('cancel') } </script> <style scoped> .upload-container { margin-bottom: 20px; display: flex; flex-direction: column; } .file-upload-row { display: flex; align-items: flex-start; gap: 10px; margin-bottom: 10px; } .upload-area-container { display: flex; flex-direction: column; flex: 1; } .upload-area { border: 2px dashed #dcdfe6; border-radius: 6px; padding: 40px 20px; text-align: center; cursor: pointer; transition: all 0.3s; position: relative; width: 100%; } .upload-area.dragover { border-color: #409eff; background-color: #f5f7fa; } .upload-text { font-size: 16px; color: #606266; } .click-upload { color: #409eff; margin-left: 5px; } .file-types { margin-top: 5px; text-align: center; font-size: 14px; color: #909399; } .file-list { margin-top: 20px; border: 1px solid #ebeef5; border-radius: 4px; padding: 10px; } .file-item { display: flex; align-items: center; padding: 8px; background: #f5f7fa; border-radius: 4px; margin-bottom: 5px; } .file-name { flex: 1; margin-left: 10px; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .delete-icon { cursor: pointer; color: #f56c6c; } .dialog-btn { width: 80px; } .file-label { display: flex; min-width: 100px; font-size: 14px; color: #606266; padding-top: 5px; } .required { color: #ff4d4f; margin-right: 4px; } .error-message { color: #ff4d4f; font-size: 12px; margin-top: 4px; display: block; height: 16px; line-height: 16px; } .file-input { displa } } } .el-upload__tip { line-height: 15px; text-align: center; } } </style> 怎末修改上述代码 实现功能
09-02
基于数据驱动的 Koopman 算子的递归神经网络模型线性化,用于纳米定位系统的预测控制研究(Matlab代码实现)内容概要:本文围绕“基于数据驱动的Koopman算子的递归神经网络模型线性化”展开,旨在研究纳米定位系统的预测控制方法。通过结合数据驱动技术与Koopman算子理论,将非线性系统动态近似为高维线性系统,进而利用递归神经网络(RNN)建模并实现系统行为的精确预测。文中详细阐述了模型构建流程、线性化策略及在预测控制中的集成应用,并提供了完整的Matlab代码实现,便于科研人员复现实验、优化算法并拓展至其他精密控制系统。该方法有效提升了纳米级定位系统的控制精度与动态响应性能。; 适合人群:具备自动控制、机器学习或信号处理背景,熟悉Matlab编程,从事精密仪器控制、智能制造或先进控制算法研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①实现非线性动态系统的数据驱动线性化建模;②提升纳米定位平台的轨迹跟踪与预测控制性能;③为高精度控制系统提供可复现的Koopman-RNN融合解决方案; 阅读建议:建议结合Matlab代码逐段理解算法实现细节,重点关注Koopman观测矩阵构造、RNN训练流程与模型预测控制器(MPC)的集成方式,鼓励在实际硬件平台上验证并调整参数以适应具体应用场景。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值