Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
ai-box
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
青山
ai-box
Commits
85f9803e
Commit
85f9803e
authored
Jun 13, 2025
by
青山
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
代码修改
parent
73c391f4
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
13 additions
and
276 deletions
+13
-276
BackgroundRemover.jsx
src/components/BackgroundRemover.jsx
+13
-276
No files found.
src/components/BackgroundRemover.jsx
View file @
85f9803e
import
React
,
{
useState
,
useRef
}
from
'react'
;
import
{
removeBackground
}
from
"@imgly/background-removal"
;
import
styled
from
'styled-components'
;
import
{
useTranslation
}
from
'../js/i18n'
;
import
SEO
from
'./SEO'
;
import
{
useScrollToTop
}
from
'../hooks/useScrollToTop'
;
import
{
usePageLoading
}
from
'../hooks/usePageLoading'
;
import
LoadingOverlay
from
'./LoadingOverlay'
;
// Reuse container style
const
Container
=
styled
.
div
`
min-height: 100vh;
background: linear-gradient(135deg, #f5f7ff 0%, #ffffff 100%);
padding: 4rem 2rem 2rem;
position: relative;
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background:
linear-gradient(90deg, rgba(99, 102, 241, 0.05) 1px, transparent 1px),
linear-gradient(rgba(99, 102, 241, 0.05) 1px, transparent 1px);
background-size: 20px 20px;
pointer-events: none;
}
`
;
const
ContentWrapper
=
styled
.
div
`
display: flex;
gap: 2rem;
max-width: 1400px;
margin: 0 auto;
position: relative;
z-index: 1;
height: calc(100vh - 6rem);
@media (max-width: 768px) {
flex-direction: column;
height: auto;
}
`
;
const
Title
=
styled
.
h2
`
font-size: 1.8rem;
margin-bottom: 1.5rem;
background: linear-gradient(135deg, #6366F1 0%, #4F46E5 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
font-weight: 700;
letter-spacing: -0.02em;
`
;
const
PreviewArea
=
styled
.
div
`
flex: 2;
display: flex;
flex-direction: column;
gap: 1rem;
background: white;
border-radius: 16px;
padding: 1.5rem;
box-shadow: 0 8px 32px rgba(99, 102, 241, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
height: 100%;
overflow: hidden;
position: relative;
.preview-content {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
position: relative;
overflow: hidden;
}
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 1rem;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.9);
z-index: 10;
opacity: 1;
transition: opacity 0.3s ease-in-out;
&.hide {
opacity: 0;
pointer-events: none;
}
}
.upload-prompt {
color: #666;
font-size: 1.2rem;
}
`
;
const
ControlPanel
=
styled
.
div
`
flex: 1;
background: rgba(255, 255, 255, 0.8);
backdrop-filter: blur(10px);
border-radius: 16px;
padding: 1.5rem;
box-shadow: 0 8px 32px rgba(99, 102, 241, 0.1);
border: 1px solid rgba(255, 255, 255, 0.2);
display: flex;
flex-direction: column;
gap: 1rem;
`
;
const
ImageUploadArea
=
styled
.
div
`
border: 2px dashed #6366F1;
border-radius: 8px;
padding: 2rem;
text-align: center;
cursor: pointer;
transition: all 0.3s ease;
&:hover {
background: rgba(99, 102, 241, 0.05);
}
`
;
const
DownloadButton
=
styled
.
button
`
position: absolute;
top: 1.5rem;
right: 1.5rem;
z-index: 10;
background: linear-gradient(135deg, #6366F1 0%, #4F46E5 100%);
color: white;
border: none;
padding: 0.75rem 1.5rem;
border-radius: 8px;
font-weight: 600;
cursor: pointer;
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 0.5rem;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(99, 102, 241, 0.2);
}
&:disabled {
background: #ccc;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
`
;
// 添加提示语样式
const
PrivacyNote
=
styled
.
div
`
background: rgba(99, 102, 241, 0.1);
border-left: 4px solid #6366F1;
padding: 1rem;
margin-top: 1rem;
border-radius: 0 8px 8px 0;
color: #4F46E5;
font-size: 0.9rem;
line-height: 1.5;
`
;
import
React
from
'react'
;
function
BackgroundRemover
()
{
useScrollToTop
();
const
{
t
}
=
useTranslation
();
const
isPageLoading
=
usePageLoading
();
const
[
selectedImage
,
setSelectedImage
]
=
useState
(
null
);
const
[
removedBgImage
,
setRemovedBgImage
]
=
useState
(
null
);
const
[
isProcessing
,
setIsProcessing
]
=
useState
(
false
);
const
fileInputRef
=
useRef
(
null
);
const
handleImageUpload
=
async
(
e
)
=>
{
const
file
=
e
.
target
.
files
?.[
0
];
if
(
file
)
{
try
{
setIsProcessing
(
true
);
const
imageUrl
=
URL
.
createObjectURL
(
file
);
setSelectedImage
(
imageUrl
);
// Remove background
const
imageBlob
=
await
removeBackground
(
imageUrl
);
const
removedBgUrl
=
URL
.
createObjectURL
(
imageBlob
);
setRemovedBgImage
(
removedBgUrl
);
}
catch
(
error
)
{
console
.
error
(
'Error processing image:'
,
error
);
}
finally
{
setIsProcessing
(
false
);
}
}
};
const
handleDownload
=
()
=>
{
if
(
removedBgImage
)
{
const
link
=
document
.
createElement
(
'a'
);
link
.
href
=
removedBgImage
;
link
.
download
=
'removed-background.png'
;
document
.
body
.
appendChild
(
link
);
link
.
click
();
document
.
body
.
removeChild
(
link
);
}
};
return
(
<>
<
SEO
title=
{
t
(
'tools.imageBackgroundRemover.title'
)
}
description=
{
t
(
'tools.imageBackgroundRemover.description'
)
}
/>
{
(
isPageLoading
||
isProcessing
)
&&
<
LoadingOverlay
/>
}
<
Container
>
<
ContentWrapper
>
<
ControlPanel
>
<
Title
>
{
t
(
'tools.imageBackgroundRemover.title'
)
}
</
Title
>
<
ImageUploadArea
onClick=
{
()
=>
fileInputRef
.
current
.
click
()
}
>
<
input
type=
"file"
ref=
{
fileInputRef
}
style=
{
{
display
:
'none'
}
}
accept=
"image/*"
onChange=
{
handleImageUpload
}
/>
{
t
(
'tools.imageBackgroundRemover.uploadPrompt'
)
}
</
ImageUploadArea
>
<
PrivacyNote
>
{
t
(
'tools.imageBackgroundRemover.privacyNote'
)
}
</
PrivacyNote
>
</
ControlPanel
>
<
PreviewArea
>
{
removedBgImage
&&
(
<
DownloadButton
onClick=
{
handleDownload
}
>
{
t
(
'tools.imageBackgroundRemover.download'
)
}
</
DownloadButton
>
)
}
<
div
className=
"preview-content"
>
{
removedBgImage
?
(
<
div
style=
{
{
position
:
'relative'
,
width
:
'100%'
,
height
:
'100%'
,
display
:
'flex'
,
justifyContent
:
'center'
,
alignItems
:
'center'
}
}
>
<
img
src=
{
removedBgImage
}
alt=
"Processed"
style=
{
{
maxWidth
:
'100%'
,
maxHeight
:
'100%'
,
objectFit
:
'contain'
}
}
/>
</
div
>
)
:
(
<
div
className=
"upload-prompt"
>
{
t
(
'tools.imageBackgroundRemover.noImage'
)
}
</
div
>
)
}
</
div
>
</
PreviewArea
>
</
ContentWrapper
>
</
Container
>
</>
<
iframe
src=
"https://fishersama.com/background-remover"
title=
"Background Remover"
style=
{
{
width
:
'100%'
,
height
:
'100vh'
,
border
:
'none'
,
minHeight
:
400
,
}
}
allow=
"clipboard-write"
/>
);
}
export
default
BackgroundRemover
;
\ No newline at end of file
export
default
BackgroundRemover
;
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment