Это мой код, который обрабатывает сводки. Я проверил документацию Gemini 1.5 Flash API и обнаружил некоторые ограничения, связанные с длиной или разрешением, с которым изображение (в виде строки base64) передается в Gemini/Vertex. ИИ. Я работаю с файлами изображений размером около 2 МБ.
Код: Выделить всё
# Function to generate image summaries using Gemini API
def generate_image_summary(image_path):
global summaryllm
try:
# Read image with PIL first to ensure it's valid
with Image.open(image_path) as img:
# Convert to RGB if necessary
if img.mode not in ('RGB', 'RGBA'):
img = img.convert('RGB')
# Save to bytes with controlled settings
buffer = io.BytesIO()
img.save(
buffer,
format="PNG",
optimize=True,
)
# Get binary data
binary_data = buffer.getvalue()
#buffer.seek(0)
#image_bytes = buffer.read()
# Encode to base64 with proper padding
base64_image = base64.b64encode(binary_data).decode('utf-8')
# Ensure proper MIME type in data URL
image_url = f"data:image/png;base64,{base64_image}"
print("The image URL is:", image_url)
# Validate the base64 string
try:
# Test decode to verify the base64 string is valid
# base64.b64decode(base64_image)
test_decode = base64.b64decode(base64_image)
# Verify the decoded data matches the original
if test_decode != binary_data:
raise ValueError("Base64 encoding/decoding verification failed")
except Exception as e:
raise ValueError(f"Invalid base64 encoding: {str(e)}")
summary = summaryllm.invoke(
[
HumanMessage(
content=[
{"type": "text", "text": summary_prompt},
{"type": "image_url", "image_url": image_url},
]
)
]
)
return summary.content
except Exception as e:
st.error(f"Error processing image {image_path}: {str(e)}")
return None
# Read the image from the file and convert it to Base64
#with open(image_path, "rb") as img_file:
#buffer = img_file.read()
#base64_image = base64.b64encode(buffer).decode("utf-8")
#image_url = f"data:image/png;base64,{base64_image}"
#print("The image URL is:", image_url)
#summary = summaryllm.invoke(
# [
#HumanMessage(
#content=[
#{"type": "text", "text": summary_prompt},
#{"type": "image_url", "image_url": image_url},
#]
#)
#]
#)
#return summary.content
# Function to generate an overall summary of image summaries
def generate_overall_summary(image_summaries):
global summaryllm
# Combine all image summaries into a single text
combined_summaries = "\n\n".join([doc.page_content for doc in image_summaries])
message = HumanMessage(
content=[
{"type": "text", "text": overallsummary_prompt},
{"type": "text", "text": f"{combined_summaries}"}
]
)
# Generate the summary using the LLM
overall_summary = summaryllm.invoke([message])
return overall_summary.content
Мой процесс преобразования base64 начинается с открытие файла с помощью метода io или BytesIO. Это показано в этом фрагменте кода:
Код: Выделить всё
# Function to save a PDF page as an image
def save_pdf_page_as_image(pdf_path, output_folder, page_index, image_hashes, poppler_path):
try:
images = convert_from_path(pdf_path, first_page=page_index + 1, last_page=page_index + 1, poppler_path=poppler_path, fmt="PNG", dpi=300)
if not images:
raise ValueError("No images generated from PDF.")
except Exception as e:
st.error(f"Error processing PDF page: {e}")
return None
image = images[0] # Get the single page we are processing
# Ensure image is in RGB mode
if image.mode != 'RGB':
image = image.convert('RGB')
# Convert image to bytes for hashing
image_bytes_io = io.BytesIO()
image.save(image_bytes_io,
format="PNG",
optimize=True
)
image_bytes = image_bytes_io.getvalue()
# Compute image hash for uniqueness
image_hash = hashlib.md5(image_bytes).hexdigest()
if image_hash not in image_hashes:
# Save the image locally
image_name = f"{os.path.splitext(os.path.basename(pdf_path))[0]}_page{page_index + 1}_image.png"
image_path = os.path.join(output_folder, image_name)
#image.save(image_path)
# Save the image to disk with the same settings
with open(image_path, 'wb') as f:
f.write(image_bytes)
#image.save(
#image_path,
#format="PNG",
#optimize=True,
#quality=95
#)
# Add hash to the list to avoid duplicates
image_hashes.append(image_hash)
# Return the image path (no Base64 generation here)
return image_path
return None
Код: Выделить всё
@st.cache_resource(show_spinner=False)
def process_and_embed_assignments(assignment_batches):
global embeddings
for pdfs in assignment_batches:
# Initialize empty lists for the current function's scope.
image_paths = []
image_hashes = []
image_summaries = []
temp_pdf_path = f"./{pdfs.name}"
with open(temp_pdf_path, mode='wb') as w:
w.write(pdfs.getvalue())
#Extract images from the PDF
pdf_name = os.path.splitext(os.path.basename(temp_pdf_path))[0]
# Define the folder to save images
output_folder = f"Images//{pdf_name}"
os.makedirs(output_folder, exist_ok=True)
# Iterate over each page and save it as an image using pdf2image
pdf_info = convert_from_path(temp_pdf_path, poppler_path=popular_path)
total_pages = len(pdf_info)
for page_index in range(total_pages):
image_path = save_pdf_page_as_image(temp_pdf_path, output_folder, page_index, image_hashes, popular_path)
if image_path:
image_paths.append(image_path)
# remove temporary pdf
os.remove(f"./{pdfs.name}")
# Generate summaries for the extracted images
# for image_path in image_paths:
for page_index, images in enumerate(image_paths):
image_name = f"{pdf_name}_page_{page_index + 1}.png"
if os.path.exists(image_path) and os.path.getsize(image_path) > 0:
# Process image
summary = generate_image_summary(image_path)
else:
st.error(f"Invalid or empty image file: {image_path}")
continue
summary = generate_image_summary(images)
document = Document(
page_content=summary,
metadata={"name": image_name}
)
image_summaries.append(document)
time.sleep(5) # Adjust the sleep time as needed
# Generate a summary of the summaries for the entire PDF
overall_summary_content = generate_overall_summary(image_summaries)
overall_summary_document = Document(
page_content=overall_summary_content,
metadata={"name": f"{pdf_name}_overall_summary"} # Metadata for the overall summary
)
# Add the overall summary to the image_summaries list
image_summaries.append(overall_summary_document)
Обратили внимание, что вся страница не отображается? Как показано, загружается только небольшая часть заголовка.
Сравните это с декодированной строкой base64, которая визуализирует/отображает всю страницу (небольшая цензура из соображений незначительной конфиденциальности
Я не знаю, как поступить. Я несколько раз перезапустил свой код, чтобы проверить, решит ли проблему кодирование строки с помощью значения байтов, растрового изображения или локального пути к изображению, но ничего не помогло.
/>P.S. Я использовал Claude, ChatGPT и Perplexity, чтобы предложить идеи о том, как изменить мой код, поэтому воспринимайте любой код, который я дал, как недоверие. Система обратной связи была создана для локального выполнения всех преобразований и извлечений. , отсюда и жестко запрограммированный характер моей нынешней системы.
Подробнее здесь: https://stackoverflow.com/questions/791 ... lated-ques